1937 lines
67 KiB
C++
1937 lines
67 KiB
C++
/*************************************************************************
|
|
*
|
|
* 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_stoc.hxx"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <list>
|
|
|
|
#include <unistd.h>
|
|
#include <cppuhelper/queryinterface.hxx>
|
|
#include <cppuhelper/factory.hxx>
|
|
#include <cppuhelper/weak.hxx>
|
|
#include <cppuhelper/servicefactory.hxx>
|
|
#ifndef _CPPUHELPER_IMPLBASE3_HXX
|
|
#include <cppuhelper/implbase3.hxx>
|
|
#endif
|
|
#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
|
|
#include <cppuhelper/implementationentry.hxx>
|
|
#endif
|
|
|
|
#include <uno/mapping.hxx>
|
|
#include <osl/thread.h>
|
|
|
|
#include <rtl/ustring.hxx>
|
|
#include <rtl/ustrbuf.hxx>
|
|
#include <rtl/strbuf.hxx>
|
|
#include <osl/process.h>
|
|
|
|
#include <com/sun/star/lang/XServiceInfo.hpp>
|
|
#include <com/sun/star/lang/XInitialization.hpp>
|
|
#include <com/sun/star/loader/XImplementationLoader.hpp>
|
|
#include <com/sun/star/registry/XImplementationRegistration2.hpp>
|
|
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
|
|
#include <com/sun/star/reflection/XServiceTypeDescription.hpp>
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
#include "com/sun/star/uno/RuntimeException.hpp"
|
|
|
|
#include "mergekeys.hxx"
|
|
|
|
#if defined(SAL_W32) || defined(SAL_OS2)
|
|
#include <io.h>
|
|
#endif
|
|
|
|
#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
|
|
|
|
|
|
using namespace com::sun::star;
|
|
using namespace com::sun::star::uno;
|
|
using namespace com::sun::star::loader;
|
|
using namespace com::sun::star::beans;
|
|
using namespace com::sun::star::lang;
|
|
using namespace com::sun::star::registry;
|
|
using namespace cppu;
|
|
using namespace rtl;
|
|
using namespace osl;
|
|
|
|
|
|
#define IMPLNAME "com.sun.star.comp.stoc.ImplementationRegistration"
|
|
#define SERVICENAME "com.sun.star.registry.ImplementationRegistration"
|
|
namespace stoc_impreg
|
|
{
|
|
struct StringPool
|
|
{
|
|
OUString sImplementationName;
|
|
OUString sServiceName;
|
|
OUString TMP;
|
|
OUString TEMP;
|
|
OUString slash_UNO_slash_REGISTRY_LINKS;
|
|
OUString slash_IMPLEMENTATIONS;
|
|
OUString slash_UNO;
|
|
OUString slash_UNO_slash_SERVICES;
|
|
OUString slash_UNO_slash_SINGLETONS;
|
|
OUString slash_SERVICES;
|
|
OUString slash_UNO_slash_LOCATION;
|
|
OUString slash_UNO_slash_ACTIVATOR;
|
|
OUString colon_old;
|
|
OUString com_sun_star_registry_SimpleRegistry;
|
|
OUString Registry;
|
|
StringPool()
|
|
: sImplementationName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) )
|
|
, sServiceName( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME ) )
|
|
, TMP( RTL_CONSTASCII_USTRINGPARAM( "TMP" ) )
|
|
, TEMP( RTL_CONSTASCII_USTRINGPARAM( "TEMP" ) )
|
|
, slash_UNO_slash_REGISTRY_LINKS( RTL_CONSTASCII_USTRINGPARAM("/UNO/REGISTRY_LINKS"))
|
|
, slash_IMPLEMENTATIONS( RTL_CONSTASCII_USTRINGPARAM( "/IMPLEMENTATIONS" ) )
|
|
, slash_UNO( RTL_CONSTASCII_USTRINGPARAM("/UNO"))
|
|
, slash_UNO_slash_SERVICES( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES"))
|
|
, slash_UNO_slash_SINGLETONS( RTL_CONSTASCII_USTRINGPARAM("/UNO/SINGLETONS"))
|
|
, slash_SERVICES( RTL_CONSTASCII_USTRINGPARAM("/SERVICES/") )
|
|
, slash_UNO_slash_LOCATION( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") )
|
|
, slash_UNO_slash_ACTIVATOR( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") )
|
|
, colon_old( RTL_CONSTASCII_USTRINGPARAM(":old"))
|
|
, com_sun_star_registry_SimpleRegistry(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry") )
|
|
, Registry( RTL_CONSTASCII_USTRINGPARAM("Registry") )
|
|
{}
|
|
private:
|
|
StringPool( const StringPool & );
|
|
};
|
|
|
|
const StringPool &spool()
|
|
{
|
|
static StringPool *pPool = 0;
|
|
if( ! pPool )
|
|
{
|
|
MutexGuard guard( Mutex::getGlobalMutex() );
|
|
if( ! pPool )
|
|
{
|
|
static StringPool pool;
|
|
pPool = &pool;
|
|
}
|
|
}
|
|
return *pPool;
|
|
}
|
|
}
|
|
|
|
extern rtl_StandardModuleCount g_moduleCount;
|
|
|
|
namespace stoc_bootstrap
|
|
{
|
|
Sequence< OUString > impreg_getSupportedServiceNames()
|
|
{
|
|
static Sequence < OUString > *pNames = 0;
|
|
if( ! pNames )
|
|
{
|
|
MutexGuard guard( Mutex::getGlobalMutex() );
|
|
if( !pNames )
|
|
{
|
|
static Sequence< OUString > seqNames(1);
|
|
seqNames.getArray()[0] = stoc_impreg::spool().sServiceName;
|
|
pNames = &seqNames;
|
|
}
|
|
}
|
|
return *pNames;
|
|
}
|
|
|
|
OUString impreg_getImplementationName()
|
|
{
|
|
return stoc_impreg::spool().sImplementationName;
|
|
}
|
|
}
|
|
|
|
namespace stoc_impreg
|
|
{
|
|
//*************************************************************************
|
|
// static deleteAllLinkReferences()
|
|
//
|
|
static void deleteAllLinkReferences(const Reference < XSimpleRegistry >& xReg,
|
|
const Reference < XRegistryKey >& xSource)
|
|
// throw ( InvalidRegistryException, RuntimeException )
|
|
{
|
|
Reference < XRegistryKey > xKey = xSource->openKey(
|
|
spool().slash_UNO_slash_REGISTRY_LINKS );
|
|
|
|
if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
|
|
{
|
|
Sequence<OUString> linkNames = xKey->getAsciiListValue();
|
|
|
|
if (linkNames.getLength())
|
|
{
|
|
const OUString* pLinkNames = linkNames.getConstArray();
|
|
|
|
OUString aLinkName;
|
|
OUString aLinkParent;
|
|
Reference < XRegistryKey > xLinkParent;
|
|
const sal_Unicode* pTmpName = NULL;
|
|
const sal_Unicode* pShortName = NULL;
|
|
sal_Int32 sEnd = 0;
|
|
|
|
for (sal_Int32 i = 0; i < linkNames.getLength(); i++)
|
|
{
|
|
aLinkName = pLinkNames[i];
|
|
|
|
pTmpName = aLinkName.getStr();
|
|
|
|
if (pTmpName[0] != L'/')
|
|
continue;
|
|
|
|
sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
|
|
if ( nIndex == -1 )
|
|
pShortName = 0;
|
|
else
|
|
pShortName = pTmpName+nIndex;
|
|
|
|
while (pShortName && pShortName[1] == L'%')
|
|
{
|
|
nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
|
|
if ( nIndex == -1 )
|
|
pShortName = 0;
|
|
else
|
|
pShortName += nIndex+2;
|
|
}
|
|
|
|
if (pShortName)
|
|
{
|
|
aLinkName = aLinkName.copy(0, pShortName - pTmpName);
|
|
}
|
|
|
|
xReg->getRootKey()->deleteLink(aLinkName);
|
|
|
|
sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
|
|
|
|
aLinkParent = aLinkName.copy(0, sEnd);
|
|
|
|
while(aLinkParent.getLength())
|
|
{
|
|
xLinkParent = xReg->getRootKey()->openKey(aLinkParent);
|
|
|
|
if (xLinkParent.is() && (xLinkParent->getKeyNames().getLength() == 0))
|
|
{
|
|
aLinkName = aLinkParent;
|
|
|
|
xReg->getRootKey()->deleteKey(aLinkParent);
|
|
|
|
sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
|
|
|
|
aLinkParent = aLinkName.copy(0, sEnd);
|
|
} else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static prepareLink
|
|
//
|
|
static void prepareLink( const Reference < XSimpleRegistry > & xDest,
|
|
const Reference < XRegistryKey > & xSource,
|
|
const OUString& link)
|
|
// throw ( InvalidRegistryException, RuntimeException )
|
|
{
|
|
OUString linkRefName = xSource->getKeyName();
|
|
OUString linkName(link);
|
|
sal_Bool isRelativ = sal_False;
|
|
|
|
const sal_Unicode* pTmpName = link.getStr();
|
|
const sal_Unicode* pShortName;
|
|
sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
|
|
if ( nIndex == -1 )
|
|
pShortName = 0;
|
|
else
|
|
pShortName = pTmpName+nIndex;
|
|
|
|
if (pTmpName[0] != L'/')
|
|
isRelativ = sal_True;
|
|
|
|
while (pShortName && pShortName[1] == L'%')
|
|
{
|
|
nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
|
|
if ( nIndex == -1 )
|
|
pShortName = 0;
|
|
else
|
|
pShortName += nIndex+2;
|
|
}
|
|
|
|
if (pShortName)
|
|
{
|
|
linkRefName = linkRefName + link.copy(pShortName - pTmpName + 1);
|
|
linkName = link.copy(0, pShortName - pTmpName);
|
|
}
|
|
|
|
if (isRelativ)
|
|
xSource->createLink(linkName, linkRefName);
|
|
else
|
|
xDest->getRootKey()->createLink(linkName, linkRefName);
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static searchImplForLink
|
|
//
|
|
static OUString searchImplForLink(
|
|
const Reference < XRegistryKey > & xRootKey,
|
|
const OUString& linkName,
|
|
const OUString& implName )
|
|
// throw ( InvalidRegistryException, RuntimeException )
|
|
{
|
|
const StringPool & pool = spool();
|
|
Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
|
|
if (xKey.is())
|
|
{
|
|
Sequence< Reference < XRegistryKey > > subKeys( xKey->openKeys() );
|
|
const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
|
|
OUString key_name( pool.slash_UNO + linkName );
|
|
|
|
for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
|
|
{
|
|
try
|
|
{
|
|
Reference < XRegistryKey > xImplKey( pSubKeys[i] );
|
|
if (xImplKey->getKeyType( key_name ) == RegistryKeyType_LINK)
|
|
{
|
|
OUString oldImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
|
|
if (implName != oldImplName)
|
|
{
|
|
return oldImplName;
|
|
}
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
return OUString();
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static searchLinkTargetForImpl
|
|
//
|
|
static OUString searchLinkTargetForImpl(const Reference < XRegistryKey >& xRootKey,
|
|
const OUString& linkName,
|
|
const OUString& implName)
|
|
// throw ( InvalidRegistryException, RuntimeException )
|
|
{
|
|
OUString ret;
|
|
|
|
// try
|
|
// {
|
|
const StringPool & pool = spool();
|
|
Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
|
|
|
|
if (xKey.is())
|
|
{
|
|
Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys();
|
|
|
|
const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
|
|
Reference < XRegistryKey > xImplKey;
|
|
|
|
for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
|
|
{
|
|
xImplKey = pSubKeys[i];
|
|
|
|
OUString tmpImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
|
|
OUString qualifiedLinkName( pool.slash_UNO );
|
|
qualifiedLinkName += linkName;
|
|
if (tmpImplName == implName &&
|
|
xImplKey->getKeyType( qualifiedLinkName ) == RegistryKeyType_LINK)
|
|
{
|
|
return xImplKey->getLinkTarget( qualifiedLinkName );
|
|
}
|
|
}
|
|
}
|
|
// }
|
|
// catch(InvalidRegistryException&)
|
|
// {
|
|
// }
|
|
|
|
return ret;
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static createUniqueSubEntry
|
|
//
|
|
static void createUniqueSubEntry(const Reference < XRegistryKey > & xSuperKey,
|
|
const OUString& value)
|
|
// throw ( InvalidRegistryException, RuntimeException )
|
|
{
|
|
if (xSuperKey.is())
|
|
{
|
|
// try
|
|
// {
|
|
if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
|
|
{
|
|
sal_Int32 length = 0;
|
|
sal_Bool bReady = sal_False;
|
|
|
|
Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
|
|
length = implEntries.getLength();
|
|
|
|
for (sal_Int32 i = 0; !bReady && (i < length); i++)
|
|
{
|
|
bReady = (implEntries.getConstArray()[i] == value);
|
|
}
|
|
|
|
if (bReady)
|
|
{
|
|
Sequence<OUString> implEntriesNew(length);
|
|
implEntriesNew.getArray()[0] = value;
|
|
|
|
for (sal_Int32 i=0, j=1; i < length; i++)
|
|
{
|
|
if (implEntries.getConstArray()[i] != value)
|
|
implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
|
|
}
|
|
xSuperKey->setAsciiListValue(implEntriesNew);
|
|
} else
|
|
{
|
|
Sequence<OUString> implEntriesNew(length+1);
|
|
implEntriesNew.getArray()[0] = value;
|
|
|
|
for (sal_Int32 i = 0; i < length; i++)
|
|
{
|
|
implEntriesNew.getArray()[i+1] = implEntries.getConstArray()[i];
|
|
}
|
|
xSuperKey->setAsciiListValue(implEntriesNew);
|
|
}
|
|
} else
|
|
{
|
|
Sequence<OUString> implEntriesNew(1);
|
|
|
|
implEntriesNew.getArray()[0] = value;
|
|
|
|
xSuperKey->setAsciiListValue(implEntriesNew);
|
|
}
|
|
// }
|
|
// catch(InvalidRegistryException&)
|
|
// {
|
|
// }
|
|
}
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static deleteSubEntry
|
|
//
|
|
static sal_Bool deleteSubEntry(const Reference < XRegistryKey >& xSuperKey, const OUString& value)
|
|
// throw ( InvalidRegistryException, RuntimeException )
|
|
{
|
|
if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
|
|
{
|
|
Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
|
|
sal_Int32 length = implEntries.getLength();
|
|
sal_Int32 equals = 0;
|
|
sal_Bool hasNoImplementations = sal_False;
|
|
|
|
for (sal_Int32 i = 0; i < length; i++)
|
|
{
|
|
if (implEntries.getConstArray()[i] == value)
|
|
equals++;
|
|
}
|
|
|
|
if (equals == length)
|
|
{
|
|
hasNoImplementations = sal_True;
|
|
} else
|
|
{
|
|
Sequence<OUString> implEntriesNew(length - equals);
|
|
|
|
sal_Int32 j = 0;
|
|
for (sal_Int32 i = 0; i < length; i++)
|
|
{
|
|
if (implEntries.getConstArray()[i] != value)
|
|
{
|
|
implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
|
|
}
|
|
}
|
|
xSuperKey->setAsciiListValue(implEntriesNew);
|
|
}
|
|
|
|
if (hasNoImplementations)
|
|
{
|
|
return sal_True;
|
|
}
|
|
}
|
|
return sal_False;
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static prepareUserLink
|
|
//
|
|
static void prepareUserLink(const Reference < XSimpleRegistry >& xDest,
|
|
const OUString& linkName,
|
|
const OUString& linkTarget,
|
|
const OUString& implName)
|
|
// throw ( InvalidRegistryException, RuntimeException )
|
|
{
|
|
sal_Bool ret = sal_False;
|
|
|
|
Reference < XRegistryKey > xRootKey;
|
|
|
|
// try
|
|
// {
|
|
xRootKey = xDest->getRootKey();
|
|
|
|
if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
|
|
{
|
|
OUString oldImplName(searchImplForLink(xRootKey, linkName, implName));
|
|
|
|
if (oldImplName.getLength())
|
|
{
|
|
createUniqueSubEntry(xDest->getRootKey()->createKey(
|
|
linkName + spool().colon_old ), oldImplName);
|
|
}
|
|
}
|
|
// }
|
|
// catch (InvalidRegistryException&)
|
|
// {
|
|
// }
|
|
|
|
// try
|
|
// {
|
|
if (xRootKey->isValid())
|
|
{
|
|
ret = xRootKey->createLink(linkName, linkTarget);
|
|
}
|
|
// }
|
|
// catch(InvalidRegistryException&)
|
|
// {
|
|
// }
|
|
|
|
// return ret;
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static deleteUserLink
|
|
//
|
|
static void deletePathIfPossible(const Reference < XRegistryKey >& xRootKey,
|
|
const OUString& path)
|
|
{
|
|
try
|
|
{
|
|
Sequence<OUString> keyNames(xRootKey->openKey(path)->getKeyNames());
|
|
|
|
if (keyNames.getLength() == 0 &&
|
|
xRootKey->openKey(path)->getValueType() == RegistryValueType_NOT_DEFINED)
|
|
{
|
|
xRootKey->deleteKey(path);
|
|
|
|
OUString tmpPath(path);
|
|
OUString newPath = tmpPath.copy(0, tmpPath.lastIndexOf('/'));
|
|
|
|
if (newPath.getLength() > 1)
|
|
deletePathIfPossible(xRootKey, newPath);
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
//*************************************************************************
|
|
// static deleteUserLink
|
|
//
|
|
static void deleteUserLink(const Reference < XRegistryKey >& xRootKey,
|
|
const OUString& linkName,
|
|
const OUString& linkTarget,
|
|
const OUString& implName)
|
|
// throw ( InvalidRegistryException, RuntimeException )
|
|
{
|
|
sal_Bool bClean = sal_False;
|
|
|
|
if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
|
|
{
|
|
OUString tmpTarget = xRootKey->getLinkTarget(linkName);
|
|
|
|
if (tmpTarget == linkTarget)
|
|
{
|
|
xRootKey->deleteLink(linkName);
|
|
}
|
|
}
|
|
|
|
Reference < XRegistryKey > xOldKey = xRootKey->openKey(
|
|
linkName + spool().colon_old );
|
|
if (xOldKey.is())
|
|
{
|
|
sal_Bool hasNoImplementations = sal_False;
|
|
|
|
if (xOldKey->getValueType() == RegistryValueType_ASCIILIST)
|
|
{
|
|
Sequence<OUString> implEntries = xOldKey->getAsciiListValue();
|
|
sal_Int32 length = implEntries.getLength();
|
|
sal_Int32 equals = 0;
|
|
|
|
for (sal_Int32 i = 0; i < length; i++)
|
|
{
|
|
if (implEntries.getConstArray()[i] == implName)
|
|
equals++;
|
|
}
|
|
|
|
if (equals == length)
|
|
{
|
|
hasNoImplementations = sal_True;
|
|
} else
|
|
{
|
|
OUString oldImpl;
|
|
|
|
if (length > equals + 1)
|
|
{
|
|
Sequence<OUString> implEntriesNew(length - equals - 1);
|
|
|
|
sal_Int32 j = 0;
|
|
sal_Bool first = sal_True;
|
|
for (sal_Int32 i = 0; i < length; i++)
|
|
{
|
|
if (implEntries.getConstArray()[i] != implName)
|
|
{
|
|
if (first)
|
|
{
|
|
oldImpl = implEntries.getConstArray()[i];
|
|
first = sal_False;
|
|
} else
|
|
{
|
|
implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
xOldKey->setAsciiListValue(implEntriesNew);
|
|
} else
|
|
{
|
|
oldImpl = implEntries.getConstArray()[0];
|
|
rtl::OUString path(xOldKey->getKeyName());
|
|
xOldKey->closeKey();
|
|
xRootKey->deleteKey(path);
|
|
}
|
|
|
|
OUString oldTarget = searchLinkTargetForImpl(xRootKey, linkName, oldImpl);
|
|
if (oldTarget.getLength())
|
|
{
|
|
xRootKey->createLink(linkName, oldTarget);
|
|
}
|
|
}
|
|
|
|
if (hasNoImplementations)
|
|
{
|
|
bClean = sal_True;
|
|
hasNoImplementations = sal_False;
|
|
rtl::OUString path(xOldKey->getKeyName());
|
|
xOldKey->closeKey();
|
|
xRootKey->deleteKey(path);
|
|
}
|
|
}
|
|
} else
|
|
{
|
|
bClean = sal_True;
|
|
}
|
|
|
|
if (bClean)
|
|
{
|
|
OUString tmpName(linkName);
|
|
OUString path = tmpName.copy(0, tmpName.lastIndexOf('/'));
|
|
deletePathIfPossible(xRootKey, path);
|
|
}
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static prepareUserKeys
|
|
//
|
|
static void prepareUserKeys(const Reference < XSimpleRegistry >& xDest,
|
|
const Reference < XRegistryKey >& xUnoKey,
|
|
const Reference < XRegistryKey >& xKey,
|
|
const OUString& implName,
|
|
sal_Bool bRegister)
|
|
// throw ( InvalidRegistryException, RuntimeException )
|
|
{
|
|
sal_Bool hasSubKeys = sal_False;
|
|
|
|
Sequence<OUString> keyNames = xKey->getKeyNames();
|
|
|
|
OUString relativKey;
|
|
if (keyNames.getLength())
|
|
relativKey = keyNames.getConstArray()[0].copy(xKey->getKeyName().getLength()+1);
|
|
|
|
if (keyNames.getLength() == 1 &&
|
|
xKey->getKeyType(relativKey) == RegistryKeyType_LINK)
|
|
{
|
|
hasSubKeys = sal_True;
|
|
|
|
OUString linkTarget = xKey->getLinkTarget(relativKey);
|
|
OUString linkName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
|
|
|
|
linkName = linkName + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + relativKey;
|
|
|
|
if (bRegister)
|
|
{
|
|
prepareUserLink(xDest, linkName, linkTarget, implName);
|
|
} else
|
|
{
|
|
deleteUserLink(xDest->getRootKey(), linkName, linkTarget, implName);
|
|
}
|
|
} else
|
|
{
|
|
Sequence< Reference < XRegistryKey> > subKeys = xKey->openKeys();
|
|
|
|
if (subKeys.getLength())
|
|
{
|
|
hasSubKeys = sal_True;
|
|
const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
|
|
|
|
for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
|
|
{
|
|
prepareUserKeys(xDest, xUnoKey, pSubKeys[i], implName, bRegister);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (! hasSubKeys)
|
|
{
|
|
OUString keyName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
|
|
|
|
Reference < XRegistryKey > xRootKey = xDest->getRootKey();
|
|
if (bRegister)
|
|
{
|
|
createUniqueSubEntry(xRootKey->createKey(keyName), implName);
|
|
}
|
|
else
|
|
{
|
|
Reference< XRegistryKey > rKey = xRootKey->openKey(keyName);
|
|
if( rKey.is() )
|
|
{
|
|
deleteSubEntry(rKey, implName);
|
|
xRootKey->deleteKey(keyName);
|
|
}
|
|
|
|
OUString path = keyName.copy(0, keyName.lastIndexOf('/'));
|
|
if( path.getLength() )
|
|
{
|
|
deletePathIfPossible(xRootKey, path);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static deleteAllImplementations
|
|
//
|
|
static void deleteAllImplementations( const Reference < XSimpleRegistry >& xReg,
|
|
const Reference < XRegistryKey >& xSource,
|
|
const OUString& locationUrl,
|
|
std::list<OUString> & implNames)
|
|
// throw (InvalidRegistryException, RuntimeException)
|
|
{
|
|
Sequence < Reference < XRegistryKey > > subKeys = xSource->openKeys();
|
|
|
|
if (subKeys.getLength() > 0)
|
|
{
|
|
const Reference < XRegistryKey> * pSubKeys = subKeys.getConstArray();
|
|
Reference < XRegistryKey > xImplKey;
|
|
sal_Bool hasLocationUrl = sal_False;
|
|
|
|
const StringPool &pool = spool();
|
|
for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
|
|
{
|
|
xImplKey = pSubKeys[i];
|
|
Reference < XRegistryKey > xKey = xImplKey->openKey(
|
|
pool.slash_UNO_slash_LOCATION );
|
|
|
|
if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCII))
|
|
{
|
|
if (xKey->getAsciiValue() == locationUrl)
|
|
{
|
|
hasLocationUrl = sal_True;
|
|
|
|
OUString implName(xImplKey->getKeyName().getStr() + 1);
|
|
sal_Int32 firstDot = implName.indexOf('/');
|
|
|
|
if (firstDot >= 0)
|
|
implName = implName.copy(firstDot + 1);
|
|
|
|
implNames.push_back(implName);
|
|
|
|
deleteAllLinkReferences(xReg, xImplKey);
|
|
|
|
xKey = xImplKey->openKey( pool.slash_UNO );
|
|
if (xKey.is())
|
|
{
|
|
Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
|
|
|
|
if (subKeys2.getLength())
|
|
{
|
|
const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
|
|
|
|
for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
|
|
{
|
|
if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES ) &&
|
|
pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
|
|
pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_ACTIVATOR ) &&
|
|
pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ) &&
|
|
pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_LOCATION) )
|
|
{
|
|
prepareUserKeys(xReg, xKey, pSubKeys2[j], implName, sal_False);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hasLocationUrl)
|
|
{
|
|
hasLocationUrl = sal_False;
|
|
rtl::OUString path(xImplKey->getKeyName());
|
|
xImplKey->closeKey();
|
|
xReg->getRootKey()->deleteKey(path);
|
|
}
|
|
}
|
|
|
|
subKeys = xSource->openKeys();
|
|
if (subKeys.getLength() == 0)
|
|
{
|
|
rtl::OUString path(xSource->getKeyName());
|
|
xSource->closeKey();
|
|
xReg->getRootKey()->deleteKey(path);
|
|
}
|
|
} else
|
|
{
|
|
rtl::OUString path(xSource->getKeyName());
|
|
xSource->closeKey();
|
|
xReg->getRootKey()->deleteKey(path);
|
|
}
|
|
}
|
|
|
|
//==================================================================================================
|
|
static void delete_all_singleton_entries(
|
|
Reference < registry::XRegistryKey > const & xSingletons_section,
|
|
::std::list< OUString > const & impl_names )
|
|
// throw (InvalidRegistryException, RuntimeException)
|
|
{
|
|
Sequence< Reference< registry::XRegistryKey > > singletons( xSingletons_section->openKeys() );
|
|
Reference< registry::XRegistryKey > const * subkeys = singletons.getConstArray();
|
|
for ( sal_Int32 nPos = singletons.getLength(); nPos--; )
|
|
{
|
|
Reference< registry::XRegistryKey > const & xSingleton = subkeys[ nPos ];
|
|
Reference< registry::XRegistryKey > xRegisteredImplNames(
|
|
xSingleton->openKey( OUSTR("REGISTERED_BY") ) );
|
|
if (xRegisteredImplNames.is() && xRegisteredImplNames->isValid())
|
|
{
|
|
Sequence< OUString > registered_implnames;
|
|
try
|
|
{
|
|
registered_implnames = xRegisteredImplNames->getAsciiListValue();
|
|
}
|
|
catch (registry::InvalidValueException &)
|
|
{
|
|
}
|
|
OUString const * p = registered_implnames.getConstArray();
|
|
sal_Int32 nOrigRegLength = registered_implnames.getLength();
|
|
sal_Int32 nNewLength = nOrigRegLength;
|
|
for ( sal_Int32 n = nOrigRegLength; n--; )
|
|
{
|
|
OUString const & registered_implname = p[ n ];
|
|
|
|
::std::list< OUString >::const_iterator iPos( impl_names.begin() );
|
|
::std::list< OUString >::const_iterator const iEnd( impl_names.end() );
|
|
for ( ; iPos != iEnd; ++iPos )
|
|
{
|
|
if (iPos->equals( registered_implname ))
|
|
{
|
|
registered_implnames[ n ] = p[ nNewLength -1 ];
|
|
--nNewLength;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (nNewLength != nOrigRegLength)
|
|
{
|
|
if (0 == nNewLength)
|
|
{
|
|
// remove whole entry
|
|
xRegisteredImplNames->closeKey();
|
|
xSingleton->deleteKey( OUSTR("REGISTERED_BY") );
|
|
// registry key cannot provide its relative name, only absolute :(
|
|
OUString abs( xSingleton->getKeyName() );
|
|
xSingletons_section->deleteKey( abs.copy( abs.lastIndexOf( '/' ) +1 ) );
|
|
}
|
|
else
|
|
{
|
|
registered_implnames.realloc( nNewLength );
|
|
xRegisteredImplNames->setAsciiListValue( registered_implnames );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static deleteAllServiceEntries
|
|
//
|
|
static void deleteAllServiceEntries( const Reference < XSimpleRegistry >& xReg,
|
|
const Reference < XRegistryKey >& xSource,
|
|
const OUString& implName)
|
|
// throw ( InvalidRegistryException, RuntimeException )
|
|
{
|
|
Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
|
|
|
|
if (subKeys.getLength() > 0)
|
|
{
|
|
const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
|
|
Reference < XRegistryKey > xServiceKey;
|
|
sal_Bool hasNoImplementations = sal_False;
|
|
|
|
for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
|
|
{
|
|
xServiceKey = pSubKeys[i];
|
|
|
|
if (xServiceKey->getValueType() == RegistryValueType_ASCIILIST)
|
|
{
|
|
Sequence<OUString> implEntries = xServiceKey->getAsciiListValue();
|
|
sal_Int32 length = implEntries.getLength();
|
|
sal_Int32 equals = 0;
|
|
|
|
for (sal_Int32 j = 0; j < length; j++)
|
|
{
|
|
if (implEntries.getConstArray()[j] == implName)
|
|
equals++;
|
|
}
|
|
|
|
if (equals == length)
|
|
{
|
|
hasNoImplementations = sal_True;
|
|
} else
|
|
{
|
|
if (equals > 0)
|
|
{
|
|
Sequence<OUString> implEntriesNew(length-equals);
|
|
|
|
sal_Int32 j = 0;
|
|
for (sal_Int32 k = 0; k < length; k++)
|
|
{
|
|
if (implEntries.getConstArray()[k] != implName)
|
|
{
|
|
implEntriesNew.getArray()[j++] = implEntries.getConstArray()[k];
|
|
}
|
|
}
|
|
|
|
xServiceKey->setAsciiListValue(implEntriesNew);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hasNoImplementations)
|
|
{
|
|
hasNoImplementations = sal_False;
|
|
rtl::OUString path(xServiceKey->getKeyName());
|
|
xServiceKey->closeKey();
|
|
xReg->getRootKey()->deleteKey(path);
|
|
}
|
|
}
|
|
|
|
subKeys = xSource->openKeys();
|
|
if (subKeys.getLength() == 0)
|
|
{
|
|
rtl::OUString path(xSource->getKeyName());
|
|
xSource->closeKey();
|
|
xReg->getRootKey()->deleteKey(path);
|
|
}
|
|
} else
|
|
{
|
|
rtl::OUString path(xSource->getKeyName());
|
|
xSource->closeKey();
|
|
xReg->getRootKey()->deleteKey(path);
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
static bool is_supported_service(
|
|
OUString const & service_name,
|
|
Reference< reflection::XServiceTypeDescription > const & xService_td )
|
|
{
|
|
if (xService_td->getName().equals( service_name ))
|
|
return true;
|
|
Sequence< Reference< reflection::XServiceTypeDescription > > seq(
|
|
xService_td->getMandatoryServices() );
|
|
Reference< reflection::XServiceTypeDescription > const * p = seq.getConstArray();
|
|
for ( sal_Int32 nPos = seq.getLength(); nPos--; )
|
|
{
|
|
if (is_supported_service( service_name, p[ nPos ] ))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
static void insert_singletons(
|
|
Reference< registry::XSimpleRegistry > const & xDest,
|
|
Reference< registry::XRegistryKey > const & xImplKey,
|
|
Reference< XComponentContext > const & xContext )
|
|
// throw( registry::InvalidRegistryException, registry::CannotRegisterImplementationException, RuntimeException )
|
|
{
|
|
// singletons
|
|
Reference< registry::XRegistryKey > xKey( xImplKey->openKey( OUSTR("UNO/SINGLETONS") ) );
|
|
if (xKey.is() && xKey->isValid())
|
|
{
|
|
OUString implname( xImplKey->getKeyName().copy( sizeof ("/IMPLEMENTATIONS/") -1 ) );
|
|
// singleton entries
|
|
Sequence< Reference< registry::XRegistryKey > > xSingletons_section( xKey->openKeys() );
|
|
Reference< registry::XRegistryKey > const * p = xSingletons_section.getConstArray();
|
|
for ( sal_Int32 nPos = xSingletons_section.getLength(); nPos--; )
|
|
{
|
|
Reference< registry::XRegistryKey > const & xSingleton = p[ nPos ];
|
|
OUString singleton_name(
|
|
xSingleton->getKeyName().copy(
|
|
implname.getLength() + sizeof ("/IMPLEMENTATIONS//UNO/SINGLETONS/") -1 ) );
|
|
OUString service_name( xSingleton->getStringValue() );
|
|
|
|
OUString keyname( OUSTR("/SINGLETONS/") + singleton_name );
|
|
Reference< registry::XRegistryKey > xKey2( xDest->getRootKey()->openKey( keyname ) );
|
|
if (xKey2.is() && xKey2->isValid())
|
|
{
|
|
try
|
|
{
|
|
OUString existing_name( xKey2->getStringValue() );
|
|
if (! existing_name.equals( service_name ))
|
|
{
|
|
Reference< container::XHierarchicalNameAccess > xTDMgr;
|
|
OUString the_tdmgr =
|
|
OUSTR("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
|
|
xContext->getValueByName( the_tdmgr ) >>= xTDMgr;
|
|
if (! xTDMgr.is())
|
|
{
|
|
throw RuntimeException(
|
|
OUSTR("cannot get singleton ") + the_tdmgr,
|
|
Reference< XInterface >() );
|
|
}
|
|
try
|
|
{
|
|
Reference< reflection::XServiceTypeDescription > xExistingService_td;
|
|
xTDMgr->getByHierarchicalName( existing_name ) >>= xExistingService_td;
|
|
if (! xExistingService_td.is())
|
|
{
|
|
throw RuntimeException(
|
|
OUSTR("cannot get service type description: ") + existing_name,
|
|
Reference< XInterface >() );
|
|
}
|
|
|
|
// everything's fine if existing service entry supports the one
|
|
// to be registered
|
|
if (! is_supported_service( service_name, xExistingService_td ))
|
|
{
|
|
OUStringBuffer buf( 64 );
|
|
buf.appendAscii(
|
|
RTL_CONSTASCII_STRINGPARAM("existing singleton service (") );
|
|
buf.append( singleton_name );
|
|
buf.append( (sal_Unicode)'=' );
|
|
buf.append( existing_name );
|
|
buf.appendAscii(
|
|
RTL_CONSTASCII_STRINGPARAM(") does not support given one: ") );
|
|
buf.append( service_name );
|
|
throw registry::CannotRegisterImplementationException(
|
|
buf.makeStringAndClear(), Reference< XInterface >() );
|
|
}
|
|
}
|
|
catch (container::NoSuchElementException & exc)
|
|
{
|
|
throw RuntimeException(
|
|
OUSTR("cannot get service type description: ") + exc.Message,
|
|
Reference< XInterface >() );
|
|
}
|
|
}
|
|
}
|
|
catch (registry::InvalidValueException &)
|
|
{
|
|
// repair
|
|
xKey2->setStringValue( service_name );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// insert singleton entry
|
|
xKey2 = xDest->getRootKey()->createKey( keyname );
|
|
xKey2->setStringValue( service_name );
|
|
}
|
|
|
|
Reference< registry::XRegistryKey > xRegisteredImplNames(
|
|
xKey2->openKey( OUSTR("REGISTERED_BY") ) );
|
|
if (!xRegisteredImplNames.is() || !xRegisteredImplNames->isValid())
|
|
{
|
|
// create
|
|
xRegisteredImplNames = xKey2->createKey( OUSTR("REGISTERED_BY") );
|
|
}
|
|
|
|
Sequence< OUString > implnames;
|
|
try
|
|
{
|
|
implnames = xRegisteredImplNames->getAsciiListValue();
|
|
}
|
|
catch (registry::InvalidValueException &)
|
|
{
|
|
}
|
|
// check implname is already in
|
|
sal_Int32 nPos_implnames = implnames.getLength();
|
|
OUString const * pImplnames = implnames.getConstArray();
|
|
while (nPos_implnames--)
|
|
{
|
|
if (implname.equals( pImplnames[ nPos_implnames ] ))
|
|
break;
|
|
}
|
|
if (nPos_implnames < 0)
|
|
{
|
|
// append and write back
|
|
implnames.realloc( implnames.getLength() +1 );
|
|
implnames[ implnames.getLength() -1 ] = implname;
|
|
xRegisteredImplNames->setAsciiListValue( implnames );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//*************************************************************************
|
|
// static prepareRegistry
|
|
//
|
|
static void prepareRegistry(
|
|
const Reference < XSimpleRegistry >& xDest,
|
|
const Reference < XRegistryKey >& xSource,
|
|
const OUString& implementationLoaderUrl,
|
|
const OUString& locationUrl,
|
|
Reference< XComponentContext > const & xContext )
|
|
// throw ( InvalidRegistryException, CannotRegisterImplementationException, RuntimeException )
|
|
{
|
|
Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
|
|
|
|
if (!subKeys.getLength())
|
|
{
|
|
throw InvalidRegistryException(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM( "prepareRegistry(): source registry is empty" ) ),
|
|
Reference< XInterface > () );
|
|
}
|
|
|
|
const StringPool & pool = spool();
|
|
|
|
const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
|
|
Reference < XRegistryKey > xImplKey;
|
|
|
|
for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
|
|
{
|
|
xImplKey = pSubKeys[i];
|
|
|
|
Reference < XRegistryKey > xKey = xImplKey->openKey(
|
|
pool.slash_UNO_slash_SERVICES );
|
|
|
|
if (xKey.is())
|
|
{
|
|
// update entries in SERVICES section
|
|
Sequence< Reference < XRegistryKey > > serviceKeys = xKey->openKeys();
|
|
OUString implName;
|
|
|
|
if (serviceKeys.getLength())
|
|
{
|
|
const Reference < XRegistryKey > * pServiceKeys = serviceKeys.getConstArray();
|
|
|
|
implName = OUString(xImplKey->getKeyName().getStr() + 1);
|
|
sal_Int32 firstDot = implName.indexOf('/');
|
|
|
|
if (firstDot >= 0)
|
|
implName = implName.copy(firstDot + 1);
|
|
|
|
sal_Int32 offset = xKey->getKeyName().getLength() + 1;
|
|
|
|
for (sal_Int32 j = 0; j < serviceKeys.getLength(); j++)
|
|
{
|
|
OUString serviceName = pServiceKeys[j]->getKeyName().copy(offset);
|
|
|
|
createUniqueSubEntry(
|
|
xDest->getRootKey()->createKey(
|
|
pool.slash_SERVICES + serviceName ),
|
|
implName);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM( "prepareRegistry(): no service names given by component" ) ),
|
|
Reference< XInterface > () );
|
|
}
|
|
|
|
xKey = xImplKey->openKey( pool.slash_UNO );
|
|
if (xKey.is())
|
|
{
|
|
Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
|
|
|
|
if (subKeys2.getLength())
|
|
{
|
|
const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
|
|
|
|
for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
|
|
{
|
|
if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES) &&
|
|
pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
|
|
pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ))
|
|
{
|
|
prepareUserKeys(xDest, xKey, pSubKeys2[j], implName, sal_True);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// update LOCATION entry
|
|
xKey = xImplKey->createKey( pool.slash_UNO_slash_LOCATION );
|
|
|
|
if (xKey.is())
|
|
{
|
|
xKey->setAsciiValue(locationUrl);
|
|
}
|
|
|
|
// update ACTIVATOR entry
|
|
xKey = xImplKey->createKey( pool.slash_UNO_slash_ACTIVATOR );
|
|
|
|
if (xKey.is())
|
|
{
|
|
xKey->setAsciiValue(implementationLoaderUrl);
|
|
}
|
|
|
|
xKey = xImplKey->openKey( pool.slash_UNO_slash_SERVICES );
|
|
|
|
if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
|
|
{
|
|
// update link entries in REGISTRY_LINKS section
|
|
Sequence<OUString> linkNames = xKey->getAsciiListValue();
|
|
|
|
if (linkNames.getLength())
|
|
{
|
|
const OUString* pLinkNames = linkNames.getConstArray();
|
|
|
|
for (sal_Int32 j = 0; j < linkNames.getLength(); j++)
|
|
{
|
|
prepareLink(xDest, xImplKey, pLinkNames[j]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
insert_singletons( xDest, xImplKey, xContext );
|
|
}
|
|
}
|
|
|
|
|
|
static void findImplementations( const Reference < XRegistryKey > & xSource,
|
|
std::list <OUString>& implNames)
|
|
{
|
|
sal_Bool isImplKey = sal_False;
|
|
|
|
try
|
|
{
|
|
Reference < XRegistryKey > xKey = xSource->openKey(
|
|
spool().slash_UNO_slash_SERVICES );
|
|
|
|
if (xKey.is() && (xKey->getKeyNames().getLength() > 0))
|
|
{
|
|
isImplKey = sal_True;
|
|
|
|
OUString implName = OUString(xSource->getKeyName().getStr() + 1).replace('/', '.').getStr();
|
|
sal_Int32 firstDot = implName.indexOf('.');
|
|
|
|
if (firstDot >= 0)
|
|
implName = implName.copy(firstDot + 1);
|
|
|
|
implNames.push_back(implName);
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
|
|
if (isImplKey) return;
|
|
|
|
try
|
|
{
|
|
Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
|
|
|
|
if (subKeys.getLength() > 0)
|
|
{
|
|
const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
|
|
|
|
for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
|
|
{
|
|
findImplementations(pSubKeys[i], implNames);
|
|
}
|
|
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
class ImplementationRegistration
|
|
: public WeakImplHelper3< XImplementationRegistration2, XServiceInfo, XInitialization >
|
|
{
|
|
public:
|
|
ImplementationRegistration( const Reference < XComponentContext > & rSMgr );
|
|
~ImplementationRegistration();
|
|
|
|
// XServiceInfo
|
|
OUString SAL_CALL getImplementationName() throw(RuntimeException);
|
|
sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(RuntimeException);
|
|
Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw(RuntimeException);
|
|
|
|
// XImplementationRegistration
|
|
virtual void SAL_CALL registerImplementation(
|
|
const OUString& implementationLoader,
|
|
const OUString& location,
|
|
const Reference < XSimpleRegistry > & xReg)
|
|
throw( CannotRegisterImplementationException, RuntimeException );
|
|
|
|
virtual sal_Bool SAL_CALL revokeImplementation(
|
|
const OUString& location,
|
|
const Reference < XSimpleRegistry >& xReg)
|
|
throw( RuntimeException );
|
|
|
|
virtual Sequence< OUString > SAL_CALL getImplementations(
|
|
const OUString& implementationLoader,
|
|
const OUString& location)
|
|
throw( RuntimeException );
|
|
virtual Sequence< OUString > SAL_CALL checkInstantiation(
|
|
const OUString& implementationName)
|
|
throw( RuntimeException );
|
|
|
|
// XImplementationRegistration2
|
|
virtual void SAL_CALL registerImplementationWithLocation(
|
|
const OUString& implementationLoader,
|
|
const OUString& location,
|
|
const OUString& registeredLocation,
|
|
const Reference < XSimpleRegistry > & xReg)
|
|
throw( CannotRegisterImplementationException, RuntimeException );
|
|
|
|
// XInitialization
|
|
virtual void SAL_CALL initialize(
|
|
const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
|
|
throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
|
|
|
|
private: // helper methods
|
|
void prepareRegister(
|
|
const OUString& implementationLoader,
|
|
const OUString& location,
|
|
const OUString& registeredLocation,
|
|
const Reference < XSimpleRegistry > & xReg);
|
|
// throw( CannotRegisterImplementationException, RuntimeException )
|
|
|
|
static void doRegister( const Reference < XMultiComponentFactory >& xSMgr,
|
|
const Reference < XComponentContext > &xCtx,
|
|
const Reference < XImplementationLoader >& xAct,
|
|
const Reference < XSimpleRegistry >& xDest,
|
|
const OUString& implementationLoaderUrl,
|
|
const OUString& locationUrl,
|
|
const OUString& registeredLocationUrl);
|
|
/* throw ( InvalidRegistryException,
|
|
MergeConflictException,
|
|
CannotRegisterImplementationException, RuntimeException ) */
|
|
|
|
static void doRevoke( const Reference < XSimpleRegistry >& xDest,
|
|
const OUString& locationUrl );
|
|
// throw( InvalidRegistryException, RuntimeException )
|
|
Reference< XSimpleRegistry > getRegistryFromServiceManager();
|
|
|
|
static Reference< XSimpleRegistry > createTemporarySimpleRegistry(
|
|
const Reference< XMultiComponentFactory > &rSMgr,
|
|
const Reference < XComponentContext > & rCtx );
|
|
|
|
private: // members
|
|
Reference < XMultiComponentFactory > m_xSMgr;
|
|
Reference < XComponentContext > m_xCtx;
|
|
};
|
|
|
|
//*************************************************************************
|
|
// ImplementationRegistration()
|
|
//
|
|
ImplementationRegistration::ImplementationRegistration( const Reference < XComponentContext > & xCtx )
|
|
: m_xSMgr( xCtx->getServiceManager() )
|
|
, m_xCtx( xCtx )
|
|
{
|
|
g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
|
|
}
|
|
|
|
//*************************************************************************
|
|
// ~ImplementationRegistration()
|
|
//
|
|
ImplementationRegistration::~ImplementationRegistration()
|
|
{
|
|
g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
|
|
}
|
|
|
|
|
|
// XServiceInfo
|
|
OUString ImplementationRegistration::getImplementationName() throw(RuntimeException)
|
|
{
|
|
return stoc_bootstrap::impreg_getImplementationName();
|
|
}
|
|
|
|
// XServiceInfo
|
|
sal_Bool ImplementationRegistration::supportsService(const OUString& ServiceName) throw(RuntimeException)
|
|
{
|
|
Sequence< OUString > aSNL = getSupportedServiceNames();
|
|
const OUString * pArray = aSNL.getConstArray();
|
|
for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
|
|
if( pArray[i] == ServiceName )
|
|
return sal_True;
|
|
return sal_False;
|
|
}
|
|
|
|
// XServiceInfo
|
|
Sequence< OUString > ImplementationRegistration::getSupportedServiceNames(void) throw(RuntimeException)
|
|
{
|
|
return stoc_bootstrap::impreg_getSupportedServiceNames();
|
|
}
|
|
|
|
Reference< XSimpleRegistry > ImplementationRegistration::getRegistryFromServiceManager()
|
|
{
|
|
Reference < XPropertySet > xPropSet( m_xSMgr, UNO_QUERY );
|
|
Reference < XSimpleRegistry > xRegistry;
|
|
|
|
if( xPropSet.is() ) {
|
|
|
|
try { // the implementation does not support XIntrospectionAccess !
|
|
|
|
Any aAny = xPropSet->getPropertyValue( spool().Registry );
|
|
|
|
if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) {
|
|
aAny >>= xRegistry;
|
|
}
|
|
}
|
|
catch( UnknownPropertyException & ) {
|
|
// empty reference is error signal !
|
|
}
|
|
}
|
|
|
|
return xRegistry;
|
|
}
|
|
|
|
|
|
//************************************************************************
|
|
// XInitialization
|
|
//
|
|
void ImplementationRegistration::initialize(
|
|
const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArgs )
|
|
throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
|
|
{
|
|
|
|
if( aArgs.getLength() != 4 ) {
|
|
OUStringBuffer buf;
|
|
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
|
|
"ImplementationRegistration::initialize() expects 4 parameters, got "));
|
|
buf.append( (sal_Int32) aArgs.getLength() );
|
|
throw IllegalArgumentException( buf.makeStringAndClear(),
|
|
Reference<XInterface > (),
|
|
0 );
|
|
}
|
|
|
|
Reference< XImplementationLoader > rLoader;
|
|
OUString loaderServiceName;
|
|
OUString locationUrl;
|
|
Reference< XSimpleRegistry > rReg;
|
|
|
|
// 1st argument : An instance of an implementation loader
|
|
if( aArgs.getConstArray()[0].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
|
|
aArgs.getConstArray()[0] >>= rLoader;
|
|
}
|
|
if( !rLoader.is()) {
|
|
OUStringBuffer buf;
|
|
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
|
|
"ImplementationRegistration::initialize() invalid first parameter,"
|
|
"expected " ) );
|
|
buf.append( getCppuType( &rLoader ).getTypeName() );
|
|
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", got " ) );
|
|
buf.append( aArgs.getConstArray()[0].getValueTypeName() );
|
|
throw IllegalArgumentException( buf.makeStringAndClear(),
|
|
Reference< XInterface > (),
|
|
0 );
|
|
}
|
|
|
|
// 2nd argument : The service name of the loader. This name is written into the registry
|
|
if( aArgs.getConstArray()[1].getValueType().getTypeClass() == TypeClass_STRING ) {
|
|
aArgs.getConstArray()[1] >>= loaderServiceName;
|
|
}
|
|
if( ! loaderServiceName.getLength() ) {
|
|
OUStringBuffer buf;
|
|
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
|
|
"ImplementationRegistration::initialize() invalid second parameter,"
|
|
"expected string, got " ) );
|
|
buf.append( aArgs.getConstArray()[1].getValueTypeName() );
|
|
throw IllegalArgumentException( buf.makeStringAndClear(),
|
|
Reference< XInterface > (),
|
|
0 );
|
|
}
|
|
|
|
// 3rd argument : The file name of the dll, that contains the loader
|
|
if( aArgs.getConstArray()[2].getValueType().getTypeClass() == TypeClass_STRING ) {
|
|
aArgs.getConstArray()[2] >>= locationUrl;
|
|
}
|
|
if( ! locationUrl.getLength() ) {
|
|
OUStringBuffer buf;
|
|
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
|
|
"ImplementationRegistration::initialize() invalid third parameter,"
|
|
"expected string, got " ) );
|
|
buf.append( aArgs.getConstArray()[2].getValueTypeName() );
|
|
throw IllegalArgumentException( buf.makeStringAndClear(),
|
|
Reference< XInterface > (),
|
|
0 );
|
|
}
|
|
|
|
// 4th argument : The registry, the service should be written to
|
|
if( aArgs.getConstArray()[3].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
|
|
aArgs.getConstArray()[3] >>= rReg;
|
|
}
|
|
|
|
if( !rReg.is() ) {
|
|
rReg = getRegistryFromServiceManager();
|
|
if( !rReg.is() ) {
|
|
OUStringBuffer buf;
|
|
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
|
|
"ImplementationRegistration::initialize() invalid fourth parameter,"
|
|
"expected " ));
|
|
buf.append( getCppuType( &rReg ).getTypeName() );
|
|
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", got " ) );
|
|
buf.append( aArgs.getConstArray()[3].getValueTypeName() );
|
|
throw IllegalArgumentException( buf.makeStringAndClear(),
|
|
Reference< XInterface > (),
|
|
0 );
|
|
}
|
|
}
|
|
|
|
doRegister(m_xSMgr, m_xCtx, rLoader , rReg, loaderServiceName , locationUrl, locationUrl);
|
|
}
|
|
|
|
|
|
|
|
//*************************************************************************
|
|
// virtual function registerImplementationWithLocation of XImplementationRegistration2
|
|
//
|
|
void ImplementationRegistration::registerImplementationWithLocation(
|
|
const OUString& implementationLoaderUrl,
|
|
const OUString& locationUrl,
|
|
const OUString& registeredLocationUrl,
|
|
const Reference < XSimpleRegistry > & xReg)
|
|
throw( CannotRegisterImplementationException, RuntimeException )
|
|
{
|
|
prepareRegister(
|
|
implementationLoaderUrl, locationUrl, registeredLocationUrl, xReg);
|
|
}
|
|
|
|
// helper function
|
|
void ImplementationRegistration::prepareRegister(
|
|
const OUString& implementationLoaderUrl,
|
|
const OUString& locationUrl,
|
|
const OUString& registeredLocationUrl,
|
|
const Reference < XSimpleRegistry > & xReg)
|
|
// throw( CannotRegisterImplementationException, RuntimeException )
|
|
{
|
|
OUString implLoaderUrl(implementationLoaderUrl);
|
|
OUString activatorName;
|
|
|
|
if (implementationLoaderUrl.getLength() > 0)
|
|
{
|
|
OUString tmpActivator(implementationLoaderUrl);
|
|
sal_Int32 nIndex = 0;
|
|
activatorName = tmpActivator.getToken(0, ':', nIndex );
|
|
} else
|
|
{
|
|
// check locationUrl to find out what kind of loader is needed
|
|
// set iimplLoaderUrl
|
|
}
|
|
|
|
if( m_xSMgr.is() ) {
|
|
try
|
|
{
|
|
Reference < XImplementationLoader > xAct(
|
|
m_xSMgr->createInstanceWithContext(activatorName, m_xCtx) , UNO_QUERY );
|
|
if (xAct.is())
|
|
{
|
|
Reference < XSimpleRegistry > xRegistry;
|
|
|
|
if (xReg.is())
|
|
{
|
|
// registry supplied by user
|
|
xRegistry = xReg;
|
|
}
|
|
else
|
|
{
|
|
xRegistry = getRegistryFromServiceManager();
|
|
}
|
|
|
|
if ( xRegistry.is())
|
|
{
|
|
doRegister(m_xSMgr, m_xCtx, xAct, xRegistry, implLoaderUrl,
|
|
locationUrl, registeredLocationUrl);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OUStringBuffer buf( 128 );
|
|
buf.appendAscii( "ImplementationRegistration::registerImplementation() - The service " );
|
|
buf.append( activatorName );
|
|
buf.appendAscii( " cannot be instantiated\n" );
|
|
throw CannotRegisterImplementationException(
|
|
buf.makeStringAndClear(), Reference< XInterface > () );
|
|
}
|
|
}
|
|
catch( CannotRegisterImplementationException & )
|
|
{
|
|
throw;
|
|
}
|
|
catch( InvalidRegistryException & e )
|
|
{
|
|
OUStringBuffer buf;
|
|
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
|
|
"ImplementationRegistration::registerImplementation() "
|
|
"InvalidRegistryException during registration (" ));
|
|
buf.append( e.Message );
|
|
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
|
|
throw CannotRegisterImplementationException(
|
|
buf.makeStringAndClear(), Reference< XInterface > () );
|
|
}
|
|
catch( MergeConflictException & e )
|
|
{
|
|
OUStringBuffer buf;
|
|
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
|
|
"ImplementationRegistration::registerImplementation() "
|
|
"MergeConflictException during registration (" ));
|
|
buf.append( e.Message );
|
|
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
|
|
throw CannotRegisterImplementationException(
|
|
buf.makeStringAndClear(), Reference< XInterface > () );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw CannotRegisterImplementationException(
|
|
OUString(RTL_CONSTASCII_USTRINGPARAM(
|
|
"ImplementationRegistration::registerImplementation() "
|
|
"no componentcontext available to instantiate loader")),
|
|
Reference< XInterface > () );
|
|
}
|
|
}
|
|
|
|
//*************************************************************************
|
|
// virtual function registerImplementation of XImplementationRegistration
|
|
//
|
|
void ImplementationRegistration::registerImplementation(
|
|
const OUString& implementationLoaderUrl,
|
|
const OUString& locationUrl,
|
|
const Reference < XSimpleRegistry > & xReg)
|
|
throw( CannotRegisterImplementationException, RuntimeException )
|
|
{
|
|
prepareRegister(implementationLoaderUrl, locationUrl, locationUrl, xReg);
|
|
}
|
|
|
|
|
|
//*************************************************************************
|
|
// virtual function revokeImplementation of XImplementationRegistration
|
|
//
|
|
sal_Bool ImplementationRegistration::revokeImplementation(const OUString& location,
|
|
const Reference < XSimpleRegistry >& xReg)
|
|
throw ( RuntimeException )
|
|
{
|
|
sal_Bool ret = sal_False;
|
|
|
|
Reference < XSimpleRegistry > xRegistry;
|
|
|
|
if (xReg.is()) {
|
|
xRegistry = xReg;
|
|
}
|
|
else {
|
|
Reference < XPropertySet > xPropSet = Reference< XPropertySet >::query( m_xSMgr );
|
|
if( xPropSet.is() ) {
|
|
try {
|
|
Any aAny = xPropSet->getPropertyValue( spool().Registry );
|
|
|
|
if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
|
|
{
|
|
aAny >>= xRegistry;
|
|
}
|
|
}
|
|
catch ( UnknownPropertyException & ) {
|
|
}
|
|
}
|
|
}
|
|
|
|
if (xRegistry.is())
|
|
{
|
|
try
|
|
{
|
|
doRevoke(xRegistry, location);
|
|
ret = sal_True;
|
|
}
|
|
catch( InvalidRegistryException & )
|
|
{
|
|
// no way to transport the error, as no exception is specified and a runtime
|
|
// exception is not appropriate.
|
|
OSL_ENSURE( 0 , "InvalidRegistryException during revokeImplementation" );
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//*************************************************************************
|
|
// virtual function getImplementations of XImplementationRegistration
|
|
//
|
|
Sequence< OUString > ImplementationRegistration::getImplementations(
|
|
const OUString & implementationLoaderUrl,
|
|
const OUString & locationUrl)
|
|
throw ( RuntimeException )
|
|
{
|
|
OUString implLoaderUrl(implementationLoaderUrl);
|
|
OUString activatorName;
|
|
|
|
if (implementationLoaderUrl.getLength() > 0)
|
|
{
|
|
OUString tmpActivator(implementationLoaderUrl);
|
|
sal_Int32 nIndex = 0;
|
|
activatorName = tmpActivator.getToken(0, ':', nIndex );
|
|
} else
|
|
{
|
|
// check locationUrl to find out what kind of loader is needed
|
|
// set implLoaderUrl
|
|
}
|
|
|
|
if( m_xSMgr.is() ) {
|
|
|
|
Reference < XImplementationLoader > xAct(
|
|
m_xSMgr->createInstanceWithContext( activatorName, m_xCtx ), UNO_QUERY );
|
|
|
|
if (xAct.is())
|
|
{
|
|
|
|
Reference < XSimpleRegistry > xReg =
|
|
createTemporarySimpleRegistry( m_xSMgr, m_xCtx);
|
|
|
|
if (xReg.is())
|
|
{
|
|
try
|
|
{
|
|
xReg->open(OUString() /* in mem */, sal_False, sal_True);
|
|
Reference < XRegistryKey > xImpl;
|
|
|
|
{ // only necessary for deleting the temporary variable of rootkey
|
|
xImpl = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
|
|
}
|
|
if (xAct->writeRegistryInfo(xImpl, implementationLoaderUrl, locationUrl))
|
|
{
|
|
std::list <OUString> implNames;
|
|
|
|
findImplementations(xImpl, implNames);
|
|
|
|
if (!implNames.empty())
|
|
{
|
|
std::list<OUString>::const_iterator iter = implNames.begin();
|
|
|
|
Sequence<OUString> seqImpl(implNames.size());
|
|
OUString *pImplNames = seqImpl.getArray();
|
|
|
|
sal_Int32 index = 0;
|
|
while (iter != implNames.end())
|
|
{
|
|
pImplNames[index] = *iter;
|
|
index++;
|
|
++iter;
|
|
}
|
|
|
|
xImpl->closeKey();
|
|
return seqImpl;
|
|
}
|
|
}
|
|
|
|
xImpl->closeKey();
|
|
}
|
|
catch(MergeConflictException&)
|
|
{
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Sequence<OUString>();
|
|
}
|
|
|
|
//*************************************************************************
|
|
// virtual function checkInstantiation of XImplementationRegistration
|
|
//
|
|
Sequence< OUString > ImplementationRegistration::checkInstantiation(const OUString&)
|
|
throw ( RuntimeException )
|
|
{
|
|
OSL_ENSURE( sal_False, "ImplementationRegistration::checkInstantiation not implemented" );
|
|
return Sequence<OUString>();
|
|
}
|
|
|
|
//*************************************************************************
|
|
// helper function doRegistration
|
|
//
|
|
|
|
void ImplementationRegistration::doRevoke(
|
|
const Reference < XSimpleRegistry >& xDest,
|
|
const OUString& locationUrl)
|
|
// throw ( InvalidRegistryException, RuntimeException )
|
|
{
|
|
if( xDest.is() )
|
|
{
|
|
std::list<OUString> aNames;
|
|
|
|
const StringPool &pool = spool();
|
|
Reference < XRegistryKey > xRootKey( xDest->getRootKey() );
|
|
|
|
Reference < XRegistryKey > xKey =
|
|
xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
|
|
if (xKey.is() && xKey->isValid())
|
|
{
|
|
deleteAllImplementations(xDest, xKey, locationUrl, aNames);
|
|
}
|
|
|
|
xKey = xRootKey->openKey( pool.slash_SERVICES );
|
|
if (xKey.is())
|
|
{
|
|
std::list<OUString>::const_iterator iter = aNames.begin();
|
|
|
|
while (iter != aNames.end())
|
|
{
|
|
deleteAllServiceEntries(xDest, xKey, *iter);
|
|
++iter;
|
|
}
|
|
}
|
|
|
|
xKey = xRootKey->openKey( OUSTR("/SINGLETONS") );
|
|
if (xKey.is() && xKey->isValid())
|
|
{
|
|
delete_all_singleton_entries( xKey, aNames );
|
|
}
|
|
|
|
if (xRootKey.is())
|
|
xRootKey->closeKey();
|
|
if (xKey.is() && xKey->isValid() )
|
|
xKey->closeKey();
|
|
}
|
|
}
|
|
|
|
void ImplementationRegistration::doRegister(
|
|
const Reference< XMultiComponentFactory > & xSMgr,
|
|
const Reference< XComponentContext > &xCtx,
|
|
const Reference < XImplementationLoader > & xAct,
|
|
const Reference < XSimpleRegistry >& xDest,
|
|
const OUString& implementationLoaderUrl,
|
|
const OUString& locationUrl,
|
|
const OUString& registeredLocationUrl)
|
|
/* throw ( InvalidRegistryException,
|
|
MergeConflictException,
|
|
CannotRegisterImplementationException, RuntimeException ) */
|
|
{
|
|
Reference < XSimpleRegistry > xReg =
|
|
createTemporarySimpleRegistry( xSMgr, xCtx );
|
|
Reference < XRegistryKey > xSourceKey;
|
|
|
|
if (xAct.is() && xReg.is() && xDest.is())
|
|
{
|
|
try
|
|
{
|
|
xReg->open(OUString() /* in mem */, sal_False, sal_True);
|
|
|
|
{ // only necessary for deleting the temporary variable of rootkey
|
|
xSourceKey = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
|
|
}
|
|
|
|
sal_Bool bSuccess =
|
|
xAct->writeRegistryInfo(xSourceKey, implementationLoaderUrl, locationUrl);
|
|
if ( bSuccess )
|
|
{
|
|
prepareRegistry(xDest, xSourceKey, implementationLoaderUrl, registeredLocationUrl, xCtx);
|
|
|
|
xSourceKey->closeKey();
|
|
|
|
xSourceKey = xReg->getRootKey();
|
|
Reference < XRegistryKey > xDestKey = xDest->getRootKey();
|
|
mergeKeys( xDestKey, xSourceKey );
|
|
xDestKey->closeKey();
|
|
xSourceKey->closeKey();
|
|
}
|
|
else
|
|
{
|
|
throw CannotRegisterImplementationException(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM( "ImplementationRegistration::doRegistration() component registration signaled failure" ) ),
|
|
Reference< XInterface > () );
|
|
}
|
|
|
|
// Cleanup Source registry.
|
|
if ( xSourceKey->isValid() )
|
|
xSourceKey->closeKey();
|
|
}
|
|
catch(CannotRegisterImplementationException&)
|
|
{
|
|
if ( xSourceKey->isValid() )
|
|
xSourceKey->closeKey();
|
|
// and throw again
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Reference< XSimpleRegistry > ImplementationRegistration::createTemporarySimpleRegistry(
|
|
const Reference< XMultiComponentFactory > &rSMgr,
|
|
const Reference < XComponentContext > & xCtx)
|
|
{
|
|
|
|
Reference < XSimpleRegistry > xReg(
|
|
rSMgr->createInstanceWithContext(
|
|
spool().com_sun_star_registry_SimpleRegistry, xCtx ),
|
|
UNO_QUERY);
|
|
OSL_ASSERT( xReg.is() );
|
|
return xReg;
|
|
}
|
|
}
|
|
|
|
namespace stoc_bootstrap
|
|
{
|
|
//*************************************************************************
|
|
Reference<XInterface> SAL_CALL ImplementationRegistration_CreateInstance(
|
|
const Reference<XComponentContext> & xCtx ) // throw(Exception)
|
|
{
|
|
return (XImplementationRegistration *)new stoc_impreg::ImplementationRegistration(xCtx);
|
|
}
|
|
|
|
}
|
|
|