summaryrefslogtreecommitdiff
path: root/stoc/source/implementationregistration/implreg.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'stoc/source/implementationregistration/implreg.cxx')
-rw-r--r--stoc/source/implementationregistration/implreg.cxx1750
1 files changed, 1750 insertions, 0 deletions
diff --git a/stoc/source/implementationregistration/implreg.cxx b/stoc/source/implementationregistration/implreg.cxx
new file mode 100644
index 000000000000..357d9d2184e6
--- /dev/null
+++ b/stoc/source/implementationregistration/implreg.cxx
@@ -0,0 +1,1750 @@
+/*************************************************************************
+ *
+ * $RCSfile: implreg.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:29:33 $
+ *
+ * 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 <stl/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;
+}
+}
+
+