1750 lines
56 KiB
C++
1750 lines
56 KiB
C++
/*************************************************************************
|
|
*
|
|
* $RCSfile: implreg.cxx,v $
|
|
*
|
|
* $Revision: 1.2 $
|
|
*
|
|
* last change: $Author: svesik $ $Date: 2000-11-23 01:32:54 $
|
|
*
|
|
* The Contents of this file are made available subject to the terms of
|
|
* either of the following licenses
|
|
*
|
|
* - GNU Lesser General Public License Version 2.1
|
|
* - Sun Industry Standards Source License Version 1.1
|
|
*
|
|
* Sun Microsystems Inc., October, 2000
|
|
*
|
|
* GNU Lesser General Public License Version 2.1
|
|
* =============================================
|
|
* Copyright 2000 by Sun Microsystems, Inc.
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
*
|
|
* This library 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 for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*
|
|
*
|
|
* Sun Industry Standards Source License Version 1.1
|
|
* =================================================
|
|
* The contents of this file are subject to the Sun Industry Standards
|
|
* Source License Version 1.1 (the "License"); You may not use this file
|
|
* except in compliance with the License. You may obtain a copy of the
|
|
* License at http://www.openoffice.org/license.html.
|
|
*
|
|
* Software provided under this License is provided on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
|
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
|
|
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
|
|
* See the License for the specific provisions governing your rights and
|
|
* obligations concerning the Software.
|
|
*
|
|
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
|
|
*
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
*
|
|
* All Rights Reserved.
|
|
*
|
|
* Contributor(s): _______________________________________
|
|
*
|
|
*
|
|
************************************************************************/
|
|
|
|
#include <list>
|
|
|
|
#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_
|
|
#include <cppuhelper/queryinterface.hxx>
|
|
#endif
|
|
#ifndef _CPPUHELPER_FACTORY_HXX_
|
|
#include <cppuhelper/factory.hxx>
|
|
#endif
|
|
#ifndef _CPPUHELPER_WEAK_HXX_
|
|
#include <cppuhelper/weak.hxx>
|
|
#endif
|
|
|
|
#ifndef _CPPUHELPER_SERVICEFACTORY_HXX_
|
|
#include <cppuhelper/servicefactory.hxx>
|
|
#endif
|
|
#ifndef _CPPUHELPER_IMPLBASE3_HXX
|
|
#include <cppuhelper/implbase3.hxx>
|
|
#endif
|
|
|
|
#include <uno/mapping.hxx>
|
|
#include <vos/thread.hxx>
|
|
#include <vos/conditn.hxx>
|
|
|
|
#include <rtl/ustring.hxx>
|
|
|
|
#ifndef _VOS_PROCESS_HXX_
|
|
#include <vos/process.hxx>
|
|
#endif
|
|
|
|
#include <com/sun/star/lang/XServiceInfo.hpp>
|
|
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
|
|
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
|
|
#include <com/sun/star/lang/XInitialization.hpp>
|
|
#include <com/sun/star/loader/XImplementationLoader.hpp>
|
|
#include <com/sun/star/registry/XImplementationRegistration.hpp>
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
|
|
#if defined(SAL_W32) || defined(SAL_OS2)
|
|
#include <io.h>
|
|
#endif
|
|
|
|
|
|
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 vos;
|
|
|
|
namespace stoc_impreg
|
|
{
|
|
|
|
#define IMPLEMENTATION_NAME "com.sun.star.comp.stoc.ImplementationRegistration"
|
|
#define SERVICE_NAME "com.sun.star.registry.ImplementationRegistration"
|
|
|
|
//*************************************************************************
|
|
// static getTempName()
|
|
//
|
|
// Shouldn't this whole routine be rewritten ???? (jbu)
|
|
|
|
static OUString getTempName()
|
|
{
|
|
OUString uTmpPath;
|
|
OString tmpPath;
|
|
sal_Char tmpPattern[512];
|
|
sal_Char *pTmpName = NULL;
|
|
|
|
OStartupInfo StartupInfo;
|
|
|
|
if (StartupInfo.getEnvironment(OUString(RTL_CONSTASCII_USTRINGPARAM("TMP")), uTmpPath) != OStartupInfo::E_None)
|
|
{
|
|
if (StartupInfo.getEnvironment(OUString(RTL_CONSTASCII_USTRINGPARAM("TEMP")), uTmpPath) != OStartupInfo::E_None)
|
|
{
|
|
#if defined(WIN32) || defined(WNT) || defined(OS2)
|
|
tmpPath = OString("c:\\temp");
|
|
#else
|
|
tmpPath = OString("/tmp");
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if (uTmpPath.getLength())
|
|
{
|
|
tmpPath = OUStringToOString(uTmpPath, osl_getThreadTextEncoding());
|
|
}
|
|
|
|
#if defined(WIN32) || defined(WNT)
|
|
strcpy(tmpPattern, tmpPath.getStr());
|
|
strcat(tmpPattern, "\\reg_XXXXXX");
|
|
pTmpName = mktemp(tmpPattern);
|
|
#endif
|
|
|
|
#ifdef __OS2__
|
|
strcpy(tmpPattern, tempnam(NULL, "reg_"));
|
|
pTmpName = tmpPattern;
|
|
#endif
|
|
|
|
#ifdef UNX
|
|
strcpy(tmpPattern, tmpPath.getStr());
|
|
strcat(tmpPattern, "/reg_XXXXXX");
|
|
pTmpName = mktemp(tmpPattern);
|
|
#endif
|
|
|
|
return OStringToOUString(pTmpName, osl_getThreadTextEncoding());
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static deleteAllLinkReferences()
|
|
//
|
|
static void deleteAllLinkReferences(const Reference < XSimpleRegistry >& xReg,
|
|
const Reference < XRegistryKey >& xSource)
|
|
{
|
|
try
|
|
{
|
|
Reference < XRegistryKey > xKey = xSource->openKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/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.len())
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static prepareLink
|
|
//
|
|
static void prepareLink( const Reference < XSimpleRegistry > & xDest,
|
|
const Reference < XRegistryKey > & xSource,
|
|
const OUString& link)
|
|
{
|
|
try
|
|
{
|
|
OUString linkRefName = xSource->getKeyName();
|
|
OUString linkName(link);
|
|
sal_Bool isRelativ = 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);
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static searchImplForLink
|
|
//
|
|
static OUString searchImplForLink(const Reference < XRegistryKey > & xRootKey,
|
|
const OUString& linkName,
|
|
const OUString& implName)
|
|
{
|
|
OUString ret;
|
|
|
|
try
|
|
{
|
|
Reference < XRegistryKey > xKey = xRootKey->openKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/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];
|
|
|
|
try
|
|
{
|
|
if (xImplKey->getKeyType( OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO") ) + linkName) == RegistryKeyType_LINK)
|
|
{
|
|
OUString oldImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
|
|
if (implName != oldImplName)
|
|
{
|
|
ret = oldImplName;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static searchLinkTargetForImpl
|
|
//
|
|
static OUString searchLinkTargetForImpl(const Reference < XRegistryKey >& xRootKey,
|
|
const OUString& linkName,
|
|
const OUString& implName)
|
|
{
|
|
OUString ret;
|
|
|
|
try
|
|
{
|
|
Reference < XRegistryKey > xKey = xRootKey->openKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/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/"));
|
|
if (tmpImplName == implName &&
|
|
xImplKey->getKeyType(OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO") ) + linkName) == RegistryKeyType_LINK)
|
|
{
|
|
return xImplKey->getLinkTarget(OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO") ) + linkName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static createUniqueSubEntry
|
|
//
|
|
static void createUniqueSubEntry(const Reference < XRegistryKey > & xSuperKey,
|
|
const OUString& value)
|
|
{
|
|
if (xSuperKey.is())
|
|
{
|
|
try
|
|
{
|
|
if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
|
|
{
|
|
sal_Int32 entryNum = 1;
|
|
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)
|
|
{
|
|
if (xSuperKey.is())
|
|
{
|
|
try
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
}
|
|
|
|
return sal_False;
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static prepareUserLink
|
|
//
|
|
static sal_Bool prepareUserLink(const Reference < XSimpleRegistry >& xDest,
|
|
const OUString& linkName,
|
|
const OUString& linkTarget,
|
|
const OUString& implName)
|
|
{
|
|
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.len())
|
|
{
|
|
createUniqueSubEntry(xDest->getRootKey()->createKey(
|
|
linkName + OUString( RTL_CONSTASCII_USTRINGPARAM(":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('/')).getStr();
|
|
|
|
if (newPath.len() > 1)
|
|
deletePathIfPossible(xRootKey, newPath);
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
//*************************************************************************
|
|
// static deleteUserLink
|
|
//
|
|
static sal_Bool deleteUserLink(const Reference < XRegistryKey >& xRootKey,
|
|
const OUString& linkName,
|
|
const OUString& linkTarget,
|
|
const OUString& implName)
|
|
{
|
|
sal_Bool ret = sal_False;
|
|
|
|
try
|
|
{
|
|
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 + OUString( RTL_CONSTASCII_USTRINGPARAM(":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];
|
|
|
|
xOldKey->closeKey();
|
|
xRootKey->deleteKey(xOldKey->getKeyName());
|
|
}
|
|
|
|
OUString oldTarget = searchLinkTargetForImpl(xRootKey, linkName, oldImpl);
|
|
if (oldTarget.len())
|
|
{
|
|
xRootKey->createLink(linkName, oldTarget);
|
|
}
|
|
}
|
|
|
|
if (hasNoImplementations)
|
|
{
|
|
bClean = sal_True;
|
|
hasNoImplementations = sal_False;
|
|
xOldKey->closeKey();
|
|
xRootKey->deleteKey(xOldKey->getKeyName());
|
|
}
|
|
}
|
|
} else
|
|
{
|
|
bClean = sal_True;
|
|
}
|
|
|
|
if (bClean)
|
|
{
|
|
OUString tmpName(linkName);
|
|
OUString path = tmpName.copy(0, tmpName.lastIndexOf('/')).getStr();
|
|
deletePathIfPossible(xRootKey, path);
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static prepareUserKeys
|
|
//
|
|
static sal_Bool prepareUserKeys(const Reference < XSimpleRegistry >& xDest,
|
|
const Reference < XRegistryKey >& xUnoKey,
|
|
const Reference < XRegistryKey >& xKey,
|
|
const OUString& implName,
|
|
sal_Bool bRegister)
|
|
{
|
|
sal_Bool ret = sal_False;
|
|
sal_Bool hasSubKeys = sal_False;
|
|
|
|
try
|
|
{
|
|
Sequence<OUString> keyNames = xKey->getKeyNames();
|
|
|
|
OUString relativKey;
|
|
if (keyNames.getLength())
|
|
relativKey = keyNames.getConstArray()[0].copy(xKey->getKeyName().len()+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().len()));
|
|
|
|
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++)
|
|
{
|
|
ret = prepareUserKeys(xDest, xUnoKey, pSubKeys[i], implName, bRegister);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
|
|
try
|
|
{
|
|
if (hasSubKeys)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
OUString keyName(xKey->getKeyName().copy(xUnoKey->getKeyName().len()));
|
|
|
|
Reference < XRegistryKey > xRootKey = xDest->getRootKey();
|
|
if (bRegister)
|
|
{
|
|
createUniqueSubEntry(xRootKey->createKey(keyName), implName);
|
|
} else
|
|
{
|
|
if (deleteSubEntry(xRootKey->openKey(keyName), implName))
|
|
{
|
|
xRootKey->deleteKey(keyName);
|
|
|
|
OUString tmpName(keyName);
|
|
OUString path = tmpName.copy(0, tmpName.lastIndexOf('/')).getStr();
|
|
deletePathIfPossible(xRootKey, path);
|
|
}
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static deleteAllImplementations
|
|
//
|
|
static void deleteAllImplementations( const Reference < XSimpleRegistry >& xReg,
|
|
const Reference < XRegistryKey >& xSource,
|
|
const OUString& locationUrl,
|
|
std::list<OUString> & implNames)
|
|
{
|
|
try
|
|
{
|
|
Sequence < Reference < XRegistryKey > > subKeys = xSource->openKeys();
|
|
|
|
if (subKeys.getLength() > 0)
|
|
{
|
|
const Reference < XRegistryKey> * pSubKeys = subKeys.getConstArray();
|
|
Reference < XRegistryKey > xImplKey;
|
|
sal_Bool hasLocationUrl = sal_False;
|
|
|
|
for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
|
|
{
|
|
xImplKey = pSubKeys[i];
|
|
Reference < XRegistryKey > xKey = xImplKey->openKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/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.search(L'/');
|
|
|
|
if (firstDot >= 0)
|
|
implName = implName.copy(firstDot + 1);
|
|
|
|
implNames.push_back(implName);
|
|
|
|
deleteAllLinkReferences(xReg, xImplKey);
|
|
|
|
xKey = xImplKey->openKey(OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO")));
|
|
if (xKey.is())
|
|
{
|
|
Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys();
|
|
|
|
if (subKeys.getLength())
|
|
{
|
|
const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
|
|
|
|
for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
|
|
{
|
|
if (pSubKeys[i]->getKeyName() != (xImplKey->getKeyName() + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVCIES") )) &&
|
|
pSubKeys[i]->getKeyName() != (xImplKey->getKeyName() + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/REGISTRY_LINKS") )) &&
|
|
pSubKeys[i]->getKeyName() != (xImplKey->getKeyName() + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") )) &&
|
|
pSubKeys[i]->getKeyName() != (xImplKey->getKeyName() + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") )))
|
|
{
|
|
prepareUserKeys(xReg, xKey, pSubKeys[i], implName, sal_False);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hasLocationUrl)
|
|
{
|
|
hasLocationUrl = sal_False;
|
|
xImplKey->closeKey();
|
|
xReg->getRootKey()->deleteKey(xImplKey->getKeyName());
|
|
}
|
|
}
|
|
|
|
subKeys = xSource->openKeys();
|
|
if (subKeys.getLength() == 0)
|
|
{
|
|
xSource->closeKey();
|
|
xReg->getRootKey()->deleteKey(xSource->getKeyName());
|
|
}
|
|
} else
|
|
{
|
|
xSource->closeKey();
|
|
xReg->getRootKey()->deleteKey(xSource->getKeyName());
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
}
|
|
|
|
//*************************************************************************
|
|
// static deleteAllServiceEntries
|
|
//
|
|
static void deleteAllServiceEntries( const Reference < XSimpleRegistry >& xReg,
|
|
const Reference < XRegistryKey >& xSource,
|
|
const OUString& implName)
|
|
{
|
|
try
|
|
{
|
|
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 i = 0; i < length; i++)
|
|
{
|
|
if (implEntries.getConstArray()[i] == implName)
|
|
equals++;
|
|
}
|
|
|
|
if (equals == length)
|
|
{
|
|
hasNoImplementations = sal_True;
|
|
} else
|
|
{
|
|
if (equals > 0)
|
|
{
|
|
Sequence<OUString> implEntriesNew(length-equals);
|
|
|
|
sal_Int32 j = 0;
|
|
for (sal_Int32 i = 0; i < length; i++)
|
|
{
|
|
if (implEntries.getConstArray()[i] != implName)
|
|
{
|
|
implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
|
|
}
|
|
}
|
|
|
|
xServiceKey->setAsciiListValue(implEntriesNew);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hasNoImplementations)
|
|
{
|
|
hasNoImplementations = sal_False;
|
|
xServiceKey->closeKey();
|
|
xReg->getRootKey()->deleteKey(xServiceKey->getKeyName());
|
|
}
|
|
}
|
|
|
|
subKeys = xSource->openKeys();
|
|
if (subKeys.getLength() == 0)
|
|
{
|
|
xSource->closeKey();
|
|
xReg->getRootKey()->deleteKey(xSource->getKeyName());
|
|
}
|
|
} else
|
|
{
|
|
xSource->closeKey();
|
|
xReg->getRootKey()->deleteKey(xSource->getKeyName());
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
//*************************************************************************
|
|
// static prepareRegistry
|
|
//
|
|
static sal_Bool prepareRegistry(const Reference < XSimpleRegistry >& xDest,
|
|
const Reference < XRegistryKey >& xSource,
|
|
const OUString& implementationLoaderUrl,
|
|
const OUString& locationUrl)
|
|
{
|
|
sal_Bool ret = sal_False;
|
|
|
|
try
|
|
{
|
|
Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
|
|
|
|
if (!subKeys.getLength())
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
|
|
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(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/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.search(L'/');
|
|
|
|
if (firstDot >= 0)
|
|
implName = implName.copy(firstDot + 1);
|
|
|
|
sal_Int32 offset = xKey->getKeyName().len() + 1;
|
|
|
|
for (sal_Int32 i = 0; i < serviceKeys.getLength(); i++)
|
|
{
|
|
OUString serviceName = pServiceKeys[i]->getKeyName().copy(offset);
|
|
|
|
createUniqueSubEntry(
|
|
xDest->getRootKey()->createKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/SERVICES/") ) + serviceName ),
|
|
implName);
|
|
}
|
|
|
|
ret = sal_True;
|
|
}
|
|
|
|
xKey = xImplKey->openKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO") ));
|
|
if (xKey.is())
|
|
{
|
|
Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys();
|
|
|
|
if (subKeys.getLength())
|
|
{
|
|
const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
|
|
|
|
for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
|
|
{
|
|
if (pSubKeys[i]->getKeyName() != (xImplKey->getKeyName() + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVCIES") )) &&
|
|
pSubKeys[i]->getKeyName() != (xImplKey->getKeyName() + OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/REGISTRY_LINKS") )))
|
|
{
|
|
prepareUserKeys(xDest, xKey, pSubKeys[i], implName, sal_True);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// update LOCATION entry
|
|
xKey = xImplKey->createKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") ) );
|
|
|
|
if (xKey.is())
|
|
{
|
|
xKey->setAsciiValue(locationUrl);
|
|
}
|
|
|
|
// update ACTIVATOR entry
|
|
xKey = xImplKey->createKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") ) );
|
|
|
|
if (xKey.is())
|
|
{
|
|
xKey->setAsciiValue(implementationLoaderUrl);
|
|
}
|
|
|
|
// update DATA entry
|
|
//xKey = xImplKey->createKey("/DATA");
|
|
|
|
xKey = xImplKey->openKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/REGISTRY_LINKS") ) );
|
|
|
|
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 i = 0; i < linkNames.getLength(); i++)
|
|
{
|
|
prepareLink(xDest, xImplKey, pLinkNames[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
static void findImplementations( const Reference < XRegistryKey > & xSource,
|
|
std::list <OUString>& implNames)
|
|
{
|
|
sal_Bool isImplKey = sal_False;
|
|
|
|
try
|
|
{
|
|
Reference < XRegistryKey > xKey = xSource->openKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES") ) );
|
|
|
|
if (xKey.is() && (xKey->getKeyNames().getLength() > 0))
|
|
{
|
|
isImplKey = sal_True;
|
|
|
|
OUString implName = OUString(xSource->getKeyName().getStr() + 1).replace(L'/', L'.').getStr();
|
|
sal_Int32 firstDot = implName.search(L'.');
|
|
|
|
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 the implenetation of interface
|
|
// XImplementationRegistration
|
|
//
|
|
class ImplementationRegistration
|
|
: public WeakImplHelper3< XImplementationRegistration, XServiceInfo, XInitialization >
|
|
{
|
|
public:
|
|
ImplementationRegistration( const Reference < XMultiServiceFactory > & rSMgr );
|
|
~ImplementationRegistration();
|
|
|
|
// XServiceInfo
|
|
OUString SAL_CALL getImplementationName() throw();
|
|
sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw();
|
|
Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw();
|
|
static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(void) throw();
|
|
|
|
// Methoden von 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 );
|
|
|
|
public: // 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
|
|
|
|
static sal_Bool doRegistration( const Reference < XMultiServiceFactory >& xSMgr,
|
|
const Reference < XImplementationLoader >& xAct,
|
|
const Reference < XSimpleRegistry >& xDest,
|
|
const OUString& implementationLoaderUrl,
|
|
const OUString& locationUrl,
|
|
sal_Bool bRegister);
|
|
|
|
Reference< XSimpleRegistry > getRegistryFromServiceManager();
|
|
|
|
static Reference< XSimpleRegistry > createTemporarySimpleRegistry( const Reference < XMultiServiceFactory > & r );
|
|
|
|
private: // members
|
|
Reference < XMultiServiceFactory > m_xSMgr;
|
|
};
|
|
|
|
//*************************************************************************
|
|
// ImplementationRegistration()
|
|
//
|
|
ImplementationRegistration::ImplementationRegistration( const Reference < XMultiServiceFactory > & rSMgr )
|
|
: m_xSMgr( rSMgr )
|
|
{
|
|
}
|
|
|
|
//*************************************************************************
|
|
// ~ImplementationRegistration()
|
|
//
|
|
ImplementationRegistration::~ImplementationRegistration()
|
|
{
|
|
}
|
|
|
|
|
|
// XServiceInfo
|
|
OUString ImplementationRegistration::getImplementationName() throw()
|
|
{
|
|
return OUString::createFromAscii( IMPLEMENTATION_NAME );
|
|
}
|
|
|
|
// XServiceInfo
|
|
sal_Bool ImplementationRegistration::supportsService(const OUString& ServiceName) throw()
|
|
{
|
|
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()
|
|
{
|
|
return getSupportedServiceNames_Static();
|
|
}
|
|
|
|
// ORegistryServiceManager_Static
|
|
Sequence< OUString > ImplementationRegistration::getSupportedServiceNames_Static(void) throw ()
|
|
{
|
|
OUString aServiceName( OUString::createFromAscii( SERVICE_NAME ) );
|
|
Sequence< OUString > aSNS( &aServiceName, 1 );
|
|
return aSNS;
|
|
}
|
|
|
|
|
|
Reference< XSimpleRegistry > ImplementationRegistration::getRegistryFromServiceManager()
|
|
{
|
|
Reference < XPropertySet > xPropSet =
|
|
Reference< XPropertySet >::query (m_xSMgr );
|
|
Reference < XSimpleRegistry > xRegistry;
|
|
|
|
if( xPropSet.is() ) {
|
|
|
|
try { // the implementation does not support XIntrospectionAccess !
|
|
|
|
Any aAny = xPropSet->getPropertyValue(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("Registry") ) );
|
|
|
|
if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) {
|
|
aAny >>= xRegistry;
|
|
}
|
|
}
|
|
catch( UnknownPropertyException e ) {
|
|
// 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 ) {
|
|
throw IllegalArgumentException();
|
|
}
|
|
|
|
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()) {
|
|
throw IllegalArgumentException();
|
|
}
|
|
|
|
// 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() ) {
|
|
throw IllegalArgumentException();
|
|
}
|
|
|
|
// 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() ) {
|
|
throw IllegalArgumentException();
|
|
}
|
|
|
|
// 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() ) {
|
|
throw IllegalArgumentException();
|
|
}
|
|
}
|
|
|
|
|
|
// TODO : SimpleRegistry in doRegistration von hand anziehen !
|
|
if (!doRegistration(m_xSMgr, rLoader , rReg, loaderServiceName , locationUrl, sal_True)) {
|
|
throw Exception();
|
|
}
|
|
|
|
// ------------------------------------------------------------
|
|
}
|
|
|
|
|
|
|
|
//*************************************************************************
|
|
// virtual function registerImplementation of XImplementationRegistration
|
|
//
|
|
void ImplementationRegistration::registerImplementation(
|
|
const OUString& implementationLoaderUrl,
|
|
const OUString& locationUrl,
|
|
const Reference < XSimpleRegistry > & xReg)
|
|
throw( CannotRegisterImplementationException, RuntimeException )
|
|
{
|
|
OUString implLoaderUrl(implementationLoaderUrl);
|
|
OUString activatorName;
|
|
|
|
if (implementationLoaderUrl.len() > 0)
|
|
{
|
|
OUString tmpActivator(implementationLoaderUrl.getStr());
|
|
activatorName = tmpActivator.getToken(0, L':').getStr();
|
|
} else
|
|
{
|
|
// check locationUrl to find out what kind of loader is needed
|
|
// set iimplLoaderUrl
|
|
}
|
|
|
|
if( m_xSMgr.is() ) {
|
|
Reference < XImplementationLoader > xAct( m_xSMgr->createInstance(activatorName) , UNO_QUERY );
|
|
if (xAct.is())
|
|
{
|
|
Reference < XSimpleRegistry > xRegistry;
|
|
|
|
if (xReg.is())
|
|
{
|
|
// registry supplied by user
|
|
xRegistry = xReg;
|
|
}
|
|
else
|
|
{
|
|
xRegistry = getRegistryFromServiceManager();
|
|
}
|
|
|
|
if ( xRegistry.is())
|
|
{
|
|
if (!doRegistration(m_xSMgr, xAct, xRegistry, implLoaderUrl, locationUrl, sal_True))
|
|
throw CannotRegisterImplementationException();
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
throw CannotRegisterImplementationException();
|
|
}
|
|
|
|
//*************************************************************************
|
|
// 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(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("Registry") ) );
|
|
|
|
if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
|
|
{
|
|
aAny >>= xRegistry;
|
|
}
|
|
}
|
|
catch ( UnknownPropertyException e ) {
|
|
}
|
|
}
|
|
}
|
|
|
|
if (xRegistry.is())
|
|
{
|
|
ret = doRegistration(m_xSMgr, Reference< XImplementationLoader > (), xRegistry, OUString(), location, sal_False);
|
|
}
|
|
|
|
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.len() > 0)
|
|
{
|
|
OUString tmpActivator(implementationLoaderUrl.getStr());
|
|
activatorName = tmpActivator.getToken(0, L':').getStr();
|
|
} else
|
|
{
|
|
// check locationUrl to find out what kind of loader is needed
|
|
// set implLoaderUrl
|
|
}
|
|
|
|
if( m_xSMgr.is() ) {
|
|
|
|
Reference < XImplementationLoader > xAct( m_xSMgr->createInstance( activatorName ), UNO_QUERY );
|
|
|
|
if (xAct.is())
|
|
{
|
|
|
|
Reference < XSimpleRegistry > xReg = createTemporarySimpleRegistry( m_xSMgr);
|
|
|
|
if (xReg.is())
|
|
{
|
|
try
|
|
{
|
|
OUString aTempName = getTempName();
|
|
|
|
xReg->open(aTempName, sal_False, sal_True);
|
|
Reference < XRegistryKey > xImpl;
|
|
|
|
{ // only necessary for deleting the temporary variable of rootkey
|
|
xImpl = xReg->getRootKey()->createKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/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();
|
|
xReg->destroy();
|
|
return seqImpl;
|
|
}
|
|
}
|
|
|
|
xImpl->closeKey();
|
|
xReg->destroy();
|
|
}
|
|
catch(MergeConflictException&)
|
|
{
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Sequence<OUString>();
|
|
}
|
|
|
|
//*************************************************************************
|
|
// virtual function checkInstantiation of XImplementationRegistration
|
|
//
|
|
Sequence< OUString > ImplementationRegistration::checkInstantiation(const OUString& implementationName)
|
|
throw ( RuntimeException )
|
|
{
|
|
VOS_ENSHURE( sal_False, "ImplementationRegistration::checkInstantiation not implemented" );
|
|
return Sequence<OUString>();
|
|
}
|
|
|
|
//*************************************************************************
|
|
// helper function doRegistration
|
|
//
|
|
sal_Bool ImplementationRegistration::doRegistration(
|
|
const Reference< XMultiServiceFactory > & xSMgr,
|
|
const Reference < XImplementationLoader > & xAct,
|
|
const Reference < XSimpleRegistry >& xDest,
|
|
const OUString& implementationLoaderUrl,
|
|
const OUString& locationUrl,
|
|
sal_Bool bRegister)
|
|
{
|
|
sal_Bool ret = sal_False;
|
|
|
|
if (!bRegister)
|
|
{
|
|
// deregister
|
|
try
|
|
{
|
|
if( xDest.is() )
|
|
{
|
|
std::list<OUString> aNames;
|
|
|
|
Reference < XRegistryKey > xRootKey( xDest->getRootKey() );
|
|
|
|
Reference < XRegistryKey > xKey = xRootKey->openKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/IMPLEMENTATIONS") ) );
|
|
if (xKey.is())
|
|
{
|
|
deleteAllImplementations(xDest, xKey, locationUrl, aNames);
|
|
ret = sal_True;
|
|
}
|
|
|
|
|
|
xKey = xRootKey->openKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/SERVICES") ) );
|
|
if (xKey.is())
|
|
{
|
|
std::list<OUString>::const_iterator iter = aNames.begin();
|
|
|
|
while (iter != aNames.end())
|
|
{
|
|
deleteAllServiceEntries(xDest, xKey, *iter);
|
|
++iter;
|
|
}
|
|
}
|
|
|
|
if (xRootKey.is())
|
|
xRootKey->closeKey();
|
|
if (xKey.is())
|
|
xKey->closeKey();
|
|
}
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
} else
|
|
{
|
|
Reference < XSimpleRegistry > xReg = createTemporarySimpleRegistry( xSMgr );
|
|
Reference < XRegistryKey > xSourceKey;
|
|
|
|
if (xAct.is() && xReg.is() && xDest.is())
|
|
{
|
|
OUString aTempName = getTempName();
|
|
try
|
|
{
|
|
xReg->open(aTempName, sal_False, sal_True);
|
|
|
|
{ // only necessary for deleting the temporary variable of rootkey
|
|
xSourceKey = xReg->getRootKey()->createKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/IMPLEMENTATIONS") ) );
|
|
}
|
|
|
|
if (xAct->writeRegistryInfo(xSourceKey, implementationLoaderUrl, locationUrl))
|
|
{
|
|
if (prepareRegistry(xDest, xSourceKey, implementationLoaderUrl, locationUrl))
|
|
{
|
|
// Release Source key and registry.
|
|
xSourceKey->closeKey();
|
|
xReg->close();
|
|
|
|
xDest->mergeKey(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("/") ), aTempName );
|
|
|
|
ret = sal_True;
|
|
}
|
|
}
|
|
|
|
// Cleanup Source registry.
|
|
if ( xSourceKey->isValid() )
|
|
xSourceKey->closeKey();
|
|
if ( xReg->isValid() )
|
|
xReg->destroy();
|
|
else
|
|
{
|
|
xReg->open( aTempName, sal_False, sal_True );
|
|
xReg->destroy();
|
|
}
|
|
}
|
|
catch(MergeConflictException&)
|
|
{
|
|
}
|
|
catch(InvalidRegistryException&)
|
|
{
|
|
}
|
|
catch(CannotRegisterImplementationException&)
|
|
{
|
|
// destroy temp registry
|
|
if ( xSourceKey->isValid() )
|
|
xSourceKey->closeKey();
|
|
if ( xReg->isValid() )
|
|
xReg->destroy();
|
|
else
|
|
{
|
|
xReg->open( aTempName, sal_False, sal_True );
|
|
xReg->destroy();
|
|
}
|
|
// and throw again
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
Reference< XSimpleRegistry > ImplementationRegistration::createTemporarySimpleRegistry(
|
|
const ::com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory > & rSMgr)
|
|
{
|
|
|
|
Reference < XSimpleRegistry > xReg = Reference< XSimpleRegistry >::query(
|
|
rSMgr->createInstance(
|
|
OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry") ) ) );
|
|
OSL_ASSERT( xReg.is() );
|
|
// if( ! xReg.is() ) {
|
|
// // use as fallback ( bootstrap )
|
|
|
|
// Reference< XInterface > r = ::cppu::__loadLibComponentFactory(
|
|
// "simreg",
|
|
// "com.sun.star.comp.stoc.SimpleRegistry",
|
|
// rSMgr ,
|
|
// Reference < XRegistryKey >() )->createInstance();
|
|
|
|
// xReg = Reference< XSimpleRegistry > ( r , UNO_QUERY );
|
|
// }
|
|
|
|
return xReg;
|
|
}
|
|
|
|
|
|
|
|
//*************************************************************************
|
|
static Reference<XInterface> SAL_CALL ImplementationRegistration_CreateInstance( const Reference<XMultiServiceFactory> & rSMgr ) throw(Exception)
|
|
{
|
|
return (XImplementationRegistration *)new ImplementationRegistration(rSMgr);
|
|
}
|
|
|
|
}
|
|
|
|
extern "C"
|
|
{
|
|
//==================================================================================================
|
|
void SAL_CALL component_getImplementationEnvironment(
|
|
const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
|
|
{
|
|
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
|
|
}
|
|
//==================================================================================================
|
|
sal_Bool SAL_CALL component_writeInfo(
|
|
void * pServiceManager, void * pRegistryKey )
|
|
{
|
|
if (pRegistryKey)
|
|
{
|
|
try
|
|
{
|
|
Reference< XRegistryKey > xNewKey(
|
|
reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
|
|
OUString::createFromAscii( "/" IMPLEMENTATION_NAME "/UNO/SERVICES" ) ) );
|
|
|
|
const Sequence< OUString > & rSNL =
|
|
::stoc_impreg::ImplementationRegistration::getSupportedServiceNames_Static();
|
|
const OUString * pArray = rSNL.getConstArray();
|
|
for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
|
|
xNewKey->createKey( pArray[nPos] );
|
|
|
|
return sal_True;
|
|
}
|
|
catch (InvalidRegistryException &)
|
|
{
|
|
OSL_ENSHURE( sal_False, "### InvalidRegistryException!" );
|
|
}
|
|
}
|
|
return sal_False;
|
|
}
|
|
//==================================================================================================
|
|
void * SAL_CALL component_getFactory(
|
|
const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
|
|
{
|
|
void * pRet = 0;
|
|
|
|
if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
|
|
{
|
|
Reference< XSingleServiceFactory > xFactory( createSingleFactory(
|
|
reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
|
|
OUString::createFromAscii( pImplName ),
|
|
::stoc_impreg::ImplementationRegistration_CreateInstance,
|
|
::stoc_impreg::ImplementationRegistration::getSupportedServiceNames_Static() ) );
|
|
|
|
if (xFactory.is())
|
|
{
|
|
xFactory->acquire();
|
|
pRet = xFactory.get();
|
|
}
|
|
}
|
|
|
|
return pRet;
|
|
}
|
|
}
|
|
|
|
|