summaryrefslogtreecommitdiff
path: root/stoc/source/tdmanager
diff options
context:
space:
mode:
Diffstat (limited to 'stoc/source/tdmanager')
-rw-r--r--stoc/source/tdmanager/lrucache.hxx247
-rw-r--r--stoc/source/tdmanager/makefile.mk49
-rw-r--r--stoc/source/tdmanager/tdmgr.cxx1163
-rw-r--r--stoc/source/tdmanager/tdmgr_check.cxx556
-rw-r--r--stoc/source/tdmanager/tdmgr_common.hxx60
-rw-r--r--stoc/source/tdmanager/tdmgr_tdenumeration.cxx187
-rw-r--r--stoc/source/tdmanager/tdmgr_tdenumeration.hxx89
7 files changed, 2351 insertions, 0 deletions
diff --git a/stoc/source/tdmanager/lrucache.hxx b/stoc/source/tdmanager/lrucache.hxx
new file mode 100644
index 000000000000..fadc0a59b7bf
--- /dev/null
+++ b/stoc/source/tdmanager/lrucache.hxx
@@ -0,0 +1,247 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _LRU_CACHE_HXX_
+#define _LRU_CACHE_HXX_
+
+// __CACHE_DIAGNOSE forces cache size to 4 and works only for OUString keys
+// #define __CACHE_DIAGNOSE 1
+
+#include <osl/mutex.hxx>
+#include "rtl/ustring.hxx"
+
+#include <hash_map>
+
+
+/** Implementation of a least recently used (lru) cache.
+ <br>
+ @author Daniel Boelzle
+*/
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+class LRU_Cache
+{
+ struct CacheEntry
+ {
+ t_Key aKey;
+ t_Val aVal;
+ CacheEntry * pPred;
+ CacheEntry * pSucc;
+ };
+ typedef ::std::hash_map< t_Key, CacheEntry *, t_KeyHash, t_KeyEqual > t_Key2Element;
+
+ mutable ::osl::Mutex _aCacheMutex;
+ sal_Int32 _nCachedElements;
+ t_Key2Element _aKey2Element;
+
+ CacheEntry * _pBlock;
+ mutable CacheEntry * _pHead;
+ mutable CacheEntry * _pTail;
+ inline void toFront( CacheEntry * pEntry ) const;
+
+public:
+ /** Constructor:
+ <br>
+ @param nCachedElements number of elements to be cached; default param set to 128
+ */
+ inline LRU_Cache( sal_Int32 nCachedElements = 128 );
+ /** Destructor: releases all cached elements and keys.
+ <br>
+ */
+ inline ~LRU_Cache();
+
+ /** Retrieves a value from the cache. Returns default constructed value,
+ if none was found.
+ <br>
+ @param rKey a key
+ @return value
+ */
+ inline t_Val getValue( t_Key const & rKey ) const;
+ /** Sets a value to be cached for given key.
+ <br>
+ @param rKey a key
+ @param rValue a value
+ */
+ inline void setValue( t_Key const & rKey, t_Val const & rValue );
+ /** Tests whether a value is cached for given key.
+ <br>
+ @param rKey a key
+ @return true, if value is cached
+ */
+ inline sal_Bool hasValue( t_Key const & rKey ) const;
+ /** Clears the cache, thus releasing all cached elements and keys.
+ <br>
+ */
+ inline void clear();
+};
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::LRU_Cache( sal_Int32 nCachedElements )
+#ifdef __CACHE_DIAGNOSE
+ : _nCachedElements( 4 )
+#else
+ : _nCachedElements( nCachedElements )
+#endif
+ , _pBlock( 0 )
+{
+ if (_nCachedElements > 0)
+ {
+ _pBlock = new CacheEntry[_nCachedElements];
+ _pHead = _pBlock;
+ _pTail = _pBlock + _nCachedElements -1;
+ for ( sal_Int32 nPos = _nCachedElements; nPos--; )
+ {
+ _pBlock[nPos].pPred = _pBlock + nPos -1;
+ _pBlock[nPos].pSucc = _pBlock + nPos +1;
+ }
+ }
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::~LRU_Cache()
+{
+ delete [] _pBlock;
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::toFront(
+ CacheEntry * pEntry ) const
+{
+ if (pEntry != _pHead)
+ {
+ // cut out element
+ if (pEntry == _pTail)
+ {
+ _pTail = pEntry->pPred;
+ }
+ else
+ {
+ pEntry->pSucc->pPred = pEntry->pPred;
+ pEntry->pPred->pSucc = pEntry->pSucc;
+ }
+ // push to front
+ _pHead->pPred = pEntry;
+ pEntry->pSucc = _pHead;
+ _pHead = pEntry;
+ }
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline sal_Bool LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::hasValue(
+ t_Key const & rKey ) const
+{
+ ::osl::MutexGuard aGuard( _aCacheMutex );
+ typename t_Key2Element::const_iterator const iFind( _aKey2Element.find( rKey ) );
+ return (iFind != _aKey2Element.end());
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline t_Val LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::getValue(
+ t_Key const & rKey ) const
+{
+ ::osl::MutexGuard aGuard( _aCacheMutex );
+ const typename t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) );
+ if (iFind != _aKey2Element.end())
+ {
+ CacheEntry * pEntry = (*iFind).second;
+ toFront( pEntry );
+#ifdef __CACHE_DIAGNOSE
+ OSL_TRACE( "> retrieved element \"" );
+ OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ OSL_TRACE( "\" from cache <\n" );
+#endif
+ return pEntry->aVal;
+ }
+ return t_Val();
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::setValue(
+ t_Key const & rKey, t_Val const & rValue )
+{
+ if (_nCachedElements > 0)
+ {
+ ::osl::MutexGuard aGuard( _aCacheMutex );
+ typename t_Key2Element::const_iterator const iFind( _aKey2Element.find( rKey ) );
+
+ CacheEntry * pEntry;
+ if (iFind == _aKey2Element.end())
+ {
+ pEntry = _pTail; // erase last element
+#ifdef __CACHE_DIAGNOSE
+ if (pEntry->aKey.getLength())
+ {
+ OSL_TRACE( "> kicking element \"" );
+ OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ OSL_TRACE( "\" from cache <\n" );
+ }
+#endif
+ _aKey2Element.erase( pEntry->aKey );
+ _aKey2Element[ pEntry->aKey = rKey ] = pEntry;
+ }
+ else
+ {
+ pEntry = (*iFind).second;
+#ifdef __CACHE_DIAGNOSE
+ OSL_TRACE( "> replacing element \"" );
+ OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ OSL_TRACE( "\" in cache <\n" );
+#endif
+ }
+ pEntry->aVal = rValue;
+ toFront( pEntry );
+ }
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::clear()
+{
+ ::osl::MutexGuard aGuard( _aCacheMutex );
+ _aKey2Element.clear();
+ for ( sal_Int32 nPos = _nCachedElements; nPos--; )
+ {
+ _pBlock[nPos].aKey = t_Key();
+ _pBlock[nPos].aVal = t_Val();
+ }
+#ifdef __CACHE_DIAGNOSE
+ OSL_TRACE( "> cleared cache <\n" );
+#endif
+}
+
+//==================================================================================================
+struct FctHashOUString : public ::std::unary_function< ::rtl::OUString const &, size_t >
+{
+ size_t operator()( ::rtl::OUString const & rKey ) const
+ { return (size_t)rKey.hashCode(); }
+};
+
+/** Template instance for OUString keys, Any values.<br>
+*/
+typedef LRU_Cache< ::rtl::OUString, ::com::sun::star::uno::Any,
+ FctHashOUString, ::std::equal_to< ::rtl::OUString > >
+ LRU_CacheAnyByOUString;
+
+
+#endif
diff --git a/stoc/source/tdmanager/makefile.mk b/stoc/source/tdmanager/makefile.mk
new file mode 100644
index 000000000000..dbc4e762afff
--- /dev/null
+++ b/stoc/source/tdmanager/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = typemgr
+ENABLE_EXCEPTIONS=TRUE
+BOOTSTRAP_SERVICE=TRUE
+UNOUCROUT= $(OUT)$/inc$/bootstrap
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/tdmgr.obj \
+ $(SLO)$/tdmgr_check.obj \
+ $(SLO)$/tdmgr_tdenumeration.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/stoc/source/tdmanager/tdmgr.cxx b/stoc/source/tdmanager/tdmgr.cxx
new file mode 100644
index 000000000000..390881bb0d1d
--- /dev/null
+++ b/stoc/source/tdmanager/tdmgr.cxx
@@ -0,0 +1,1163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+#include "rtl/ustrbuf.hxx"
+#include <cppuhelper/factory.hxx>
+#ifndef _CPPUHELPER_IMPLBASE5_HXX_
+#include <cppuhelper/compbase5.hxx>
+#endif
+#include <cppuhelper/implbase1.hxx>
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+#include <cppuhelper/implementationentry.hxx>
+#endif
+#include "tdmgr_common.hxx"
+#include "tdmgr_tdenumeration.hxx"
+#include "lrucache.hxx"
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/reflection/XTypeDescription.hpp>
+#include <com/sun/star/reflection/XArrayTypeDescription.hpp>
+#include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
+#include <com/sun/star/reflection/XInterfaceTypeDescription.hpp>
+#include "com/sun/star/reflection/XStructTypeDescription.hpp"
+#include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include <algorithm>
+#include <vector>
+
+using namespace std;
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::reflection;
+using namespace com::sun::star::container;
+using namespace com::sun::star::registry;
+
+
+
+static const sal_Int32 CACHE_SIZE = 512;
+
+#define SERVICENAME "com.sun.star.reflection.TypeDescriptionManager"
+#define IMPLNAME "com.sun.star.comp.stoc.TypeDescriptionManager"
+
+//--------------------------------------------------------------------------------------------------
+// exported via tdmgr_common.hxx
+extern rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_bootstrap
+{
+Sequence< OUString > SAL_CALL tdmgr_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+OUString SAL_CALL tdmgr_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+}
+
+namespace stoc_tdmgr
+{
+typedef vector< Reference< XHierarchicalNameAccess > > ProviderVector;
+
+class EnumerationImpl;
+class ManagerImpl;
+
+//==================================================================================================
+class EventListenerImpl : public ImplHelper1< XEventListener >
+{
+ ManagerImpl * _pMgr;
+
+public:
+ EventListenerImpl( ManagerImpl * pMgr )
+ : _pMgr( pMgr )
+ {
+ ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt );
+ }
+ virtual ~EventListenerImpl();
+
+ // lifetime delegated to manager
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const EventObject & rEvt ) throw(::com::sun::star::uno::RuntimeException);
+};
+
+EventListenerImpl::~EventListenerImpl()
+{
+ ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt );
+}
+
+//==================================================================================================
+class ManagerImpl
+ : public WeakComponentImplHelper5< XServiceInfo,
+ XSet,
+ XHierarchicalNameAccess,
+ XTypeDescriptionEnumerationAccess,
+ XInitialization >
+{
+ friend class EnumerationImpl;
+ friend class EventListenerImpl;
+
+ Mutex _aComponentMutex;
+ Reference< XComponentContext > _xContext;
+ EventListenerImpl _aEventListener;
+
+ // elements
+ sal_Bool _bCaching;
+ LRU_CacheAnyByOUString _aElements;
+ // provider chain
+ ProviderVector _aProviders;
+
+ inline Any getSimpleType( const OUString & rName );
+
+ Reference< XTypeDescription > getInstantiatedStruct(OUString const & name);
+
+protected:
+ virtual void SAL_CALL disposing();
+
+public:
+ ManagerImpl( Reference< XComponentContext > const & xContext, sal_Int32 nCacheSize );
+ virtual ~ManagerImpl();
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const Sequence< Any > & args ) throw (Exception, RuntimeException);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // XElementAccess
+ virtual Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException);
+
+ // XEnumerationAccess
+ virtual Reference< XEnumeration > SAL_CALL createEnumeration() throw(::com::sun::star::uno::RuntimeException);
+
+ // XSet
+ virtual sal_Bool SAL_CALL has( const Any & rElement ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL insert( const Any & rElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL remove( const Any & rElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+
+ // XHierarchicalNameAccess
+ virtual Any SAL_CALL getByHierarchicalName( const OUString & rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XTypeDescriptionEnumerationAccess
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XTypeDescriptionEnumeration > SAL_CALL
+ createTypeDescriptionEnumeration(
+ const ::rtl::OUString& moduleName,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::TypeClass >& types,
+ ::com::sun::star::reflection::TypeDescriptionSearchDepth depth )
+ throw ( ::com::sun::star::reflection::NoSuchTypeNameException,
+ ::com::sun::star::reflection::InvalidTypeNameException,
+ ::com::sun::star::uno::RuntimeException );
+};
+
+//==================================================================================================
+class EnumerationImpl
+ : public WeakImplHelper1< XEnumeration >
+{
+ ManagerImpl * _pMgr;
+ size_t _nPos;
+
+public:
+ EnumerationImpl( ManagerImpl * pManager );
+ virtual ~EnumerationImpl();
+
+ // XEnumeration
+ virtual sal_Bool SAL_CALL hasMoreElements() throw(::com::sun::star::uno::RuntimeException);
+ virtual Any SAL_CALL nextElement() throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+};
+
+//##################################################################################################
+
+// lifetime delegated to manager
+//__________________________________________________________________________________________________
+void EventListenerImpl::acquire() throw()
+{
+ _pMgr->acquire();
+}
+//__________________________________________________________________________________________________
+void EventListenerImpl::release() throw()
+{
+ _pMgr->release();
+}
+
+// XEventListener
+//__________________________________________________________________________________________________
+void EventListenerImpl::disposing( const EventObject & rEvt )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ _pMgr->remove( makeAny( rEvt.Source ) );
+}
+
+//##################################################################################################
+
+//__________________________________________________________________________________________________
+EnumerationImpl::EnumerationImpl( ManagerImpl * pManager )
+ : _pMgr( pManager )
+ , _nPos( 0 )
+{
+ _pMgr->acquire();
+}
+//__________________________________________________________________________________________________
+EnumerationImpl::~EnumerationImpl()
+{
+ _pMgr->release();
+}
+
+// XEnumeration
+//__________________________________________________________________________________________________
+sal_Bool EnumerationImpl::hasMoreElements()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( _pMgr->_aComponentMutex );
+ return (_nPos < _pMgr->_aProviders.size());
+}
+//__________________________________________________________________________________________________
+Any EnumerationImpl::nextElement()
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( _pMgr->_aComponentMutex );
+ if (_nPos >= _pMgr->_aProviders.size())
+ {
+ throw NoSuchElementException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("there is no further element!") ),
+ (XWeak *)(OWeakObject *)this );
+ }
+ return makeAny( _pMgr->_aProviders[_nPos++] );
+}
+
+//##################################################################################################
+
+//__________________________________________________________________________________________________
+ManagerImpl::ManagerImpl(
+ Reference< XComponentContext > const & xContext, sal_Int32 nCacheSize )
+ : WeakComponentImplHelper5<
+ XServiceInfo, XSet, XHierarchicalNameAccess,
+ XTypeDescriptionEnumerationAccess, XInitialization >( _aComponentMutex )
+ , _xContext( xContext )
+ , _aEventListener( this )
+ , _bCaching( sal_True )
+ , _aElements( nCacheSize )
+{
+ ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+ManagerImpl::~ManagerImpl()
+{
+ OSL_ENSURE( _aProviders.size() == 0, "### still providers left!" );
+ OSL_TRACE( "> TypeDescriptionManager shut down. <\n" );
+ ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+void ManagerImpl::disposing()
+{
+ // called on disposing the tdmgr instance (supposedly from context)
+ _bCaching = sal_False;
+ _aElements.clear();
+ _xContext.clear();
+ _aProviders.clear();
+}
+
+// XInitialization
+//__________________________________________________________________________________________________
+void ManagerImpl::initialize(
+ const Sequence< Any > & args )
+ throw (Exception, RuntimeException)
+{
+ // additional providers
+ Any const * pProviders = args.getConstArray();
+ for ( sal_Int32 nPos = 0; nPos < args.getLength(); ++nPos )
+ {
+ Reference< XHierarchicalNameAccess > xHA( pProviders[ nPos ], UNO_QUERY );
+ OSL_ENSURE( xHA.is(), "### no td provider!" );
+
+ if (xHA.is())
+ {
+ try
+ {
+ insert( makeAny( xHA ) );
+ }
+ catch (IllegalArgumentException &)
+ {
+ }
+ catch (ElementExistException &)
+ {
+ }
+ }
+ }
+}
+
+// XServiceInfo
+//__________________________________________________________________________________________________
+OUString ManagerImpl::getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return stoc_bootstrap::tdmgr_getImplementationName();
+}
+//__________________________________________________________________________________________________
+sal_Bool ManagerImpl::supportsService( const OUString & rServiceName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ const Sequence< OUString > & rSNL = getSupportedServiceNames();
+ const OUString * pArray = rSNL.getConstArray();
+ for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
+ {
+ if (pArray[nPos] == rServiceName)
+ return sal_True;
+ }
+ return sal_False;
+}
+//__________________________________________________________________________________________________
+Sequence< OUString > ManagerImpl::getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return stoc_bootstrap::tdmgr_getSupportedServiceNames();
+}
+
+// XElementAccess
+//__________________________________________________________________________________________________
+Type ManagerImpl::getElementType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return ::getCppuType( (const Reference< XHierarchicalNameAccess > *)0 );
+}
+//__________________________________________________________________________________________________
+sal_Bool ManagerImpl::hasElements()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( _aComponentMutex );
+ return (_aProviders.size() > 0);
+}
+
+// XEnumerationAccess
+//__________________________________________________________________________________________________
+Reference< XEnumeration > ManagerImpl::createEnumeration()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return new EnumerationImpl( this );
+}
+
+// XSet
+//__________________________________________________________________________________________________
+sal_Bool SAL_CALL ManagerImpl::has( const Any & rElement )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Reference< XHierarchicalNameAccess > xElem;
+ if (rElement >>= xElem)
+ {
+ MutexGuard aGuard( _aComponentMutex );
+ return (find( _aProviders.begin(), _aProviders.end(), xElem ) != _aProviders.end());
+ }
+ return sal_False;
+}
+
+//__________________________________________________________________________________________________
+void SAL_CALL ManagerImpl::insert( const Any & rElement )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException)
+{
+ Reference< XHierarchicalNameAccess > xElem;
+ if (! (rElement >>= xElem) || !xElem.is())
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no valid type description provider given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+ }
+
+ MutexGuard aGuard( _aComponentMutex );
+ if (find( _aProviders.begin(), _aProviders.end(), xElem ) != _aProviders.end())
+ {
+ throw ElementExistException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("provider already inserted!") ),
+ (XWeak *)(OWeakObject *)this );
+ }
+
+ if (! _aProviders.empty())
+ {
+ // check whether all types are compatible, if possible:
+ Reference<reflection::XTypeDescriptionEnumerationAccess> xTDEnumAccess(
+ xElem, UNO_QUERY );
+ OSL_ENSURE( xTDEnumAccess.is(),
+ "### providers ought to implement "
+ "reflection::XTypeDescriptionEnumerationAccess!" );
+ if (xTDEnumAccess.is())
+ {
+ try
+ {
+ TypeClass ar [] = {
+ TypeClass_ENUM, TypeClass_TYPEDEF, TypeClass_SEQUENCE,
+ TypeClass_STRUCT, TypeClass_EXCEPTION,
+ /* TypeClass_UNION, TypeClass_ARRAY not supported */
+ TypeClass_INTERFACE,
+ TypeClass_SERVICE,
+ TypeClass_INTERFACE_METHOD, TypeClass_INTERFACE_ATTRIBUTE,
+ TypeClass_PROPERTY, TypeClass_CONSTANT, TypeClass_CONSTANTS,
+ TypeClass_SINGLETON
+ };
+ Reference<reflection::XTypeDescriptionEnumeration> xTDEnum(
+ xTDEnumAccess->createTypeDescriptionEnumeration(
+ OUString() /* all modules */,
+ Sequence<TypeClass>( ar, ARLEN(ar) ),
+ reflection::TypeDescriptionSearchDepth_INFINITE ) );
+
+ while (xTDEnum->hasMoreElements())
+ {
+ Reference<reflection::XTypeDescription> xNewTD;
+ try
+ {
+ xNewTD = xTDEnum->nextTypeDescription();
+ }
+ catch (container::NoSuchElementException & exc)
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("NoSuchElementException occured: ") +
+ exc.Message, static_cast<OWeakObject *>(this),
+ -1 /* unknown */ );
+ }
+
+ try
+ {
+ OUString newName( xNewTD->getName() );
+ Reference<reflection::XTypeDescription> xExistingTD(
+ getByHierarchicalName( newName ), UNO_QUERY );
+ OSL_ASSERT( xExistingTD.is() );
+ // existing, check whether compatible:
+ if (xExistingTD.is())
+ {
+ try
+ {
+ check( xNewTD, xExistingTD );
+ }
+ catch (IncompatibleTypeException & exc)
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("Rejecting types due to "
+ "incompatibility! ") + exc.m_cause,
+ static_cast<OWeakObject *>(this), 0 );
+ }
+ }
+ }
+ catch (container::NoSuchElementException &)
+ {
+ // type not in: ok
+ }
+ }
+ }
+ catch (reflection::NoSuchTypeNameException & exc)
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("NoSuchTypeNameException occured: ") + exc.Message,
+ static_cast<OWeakObject *>(this), -1 /* unknown */ );
+ }
+ catch (reflection::InvalidTypeNameException & exc)
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("InvalidTypeNameException occured: ") + exc.Message,
+ static_cast<OWeakObject *>(this), -1 /* unknown */ );
+ }
+ }
+ }
+
+ _aProviders.push_back( xElem );
+ Reference< XComponent > xComp( xElem, UNO_QUERY );
+ if (xComp.is())
+ xComp->addEventListener( &_aEventListener );
+}
+//__________________________________________________________________________________________________
+void SAL_CALL ManagerImpl::remove( const Any & rElement )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
+{
+ if (!rBHelper.bDisposed && !rBHelper.bInDispose)
+ {
+ Reference< XHierarchicalNameAccess > xElem;
+ if (! (rElement >>= xElem))
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no type description provider given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+ }
+
+ MutexGuard aGuard( _aComponentMutex );
+ ProviderVector::iterator iFind( find( _aProviders.begin(), _aProviders.end(), xElem ) );
+ if (iFind == _aProviders.end())
+ {
+ throw NoSuchElementException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("provider not found!") ),
+ (XWeak *)(OWeakObject *)this );
+ }
+ _aProviders.erase( iFind );
+ }
+
+ Reference< XComponent > xComp;
+ if (rElement >>= xComp)
+ xComp->removeEventListener( &_aEventListener );
+}
+
+// XTypeDescriptionEnumerationAccess
+//__________________________________________________________________________________________________
+// virtual
+Reference< XTypeDescriptionEnumeration > SAL_CALL
+ManagerImpl::createTypeDescriptionEnumeration(
+ const OUString & moduleName,
+ const Sequence< TypeClass > & types,
+ TypeDescriptionSearchDepth depth )
+ throw ( NoSuchTypeNameException,
+ InvalidTypeNameException,
+ RuntimeException )
+{
+ MutexGuard aGuard( _aComponentMutex );
+
+ TDEnumerationAccessStack aStack;
+ ProviderVector::const_iterator it = _aProviders.begin();
+ const ProviderVector::const_iterator end = _aProviders.end();
+ while ( it != end )
+ {
+ Reference< XTypeDescriptionEnumerationAccess >xEnumAccess(
+ (*it), UNO_QUERY );
+ OSL_ENSURE( xEnumAccess.is(),
+ "### no XTypeDescriptionEnumerationAccess!" );
+ if ( xEnumAccess.is() )
+ aStack.push( xEnumAccess );
+
+ it++;
+ }
+
+ return Reference< XTypeDescriptionEnumeration >(
+ new TypeDescriptionEnumerationImpl( moduleName,
+ types,
+ depth,
+ aStack ) );
+}
+
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+//==================================================================================================
+class SimpleTypeDescriptionImpl
+ : public WeakImplHelper1< XTypeDescription >
+{
+ TypeClass _eTC;
+ OUString _aName;
+
+public:
+ SimpleTypeDescriptionImpl( TypeClass eTC, const OUString & rName )
+ : _eTC( eTC )
+ , _aName( rName )
+ {}
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+};
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass SimpleTypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _eTC;
+}
+//__________________________________________________________________________________________________
+OUString SimpleTypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aName;
+}
+
+//==================================================================================================
+class SequenceTypeDescriptionImpl
+ : public WeakImplHelper1< XIndirectTypeDescription >
+{
+ Reference< XTypeDescription > _xElementTD;
+
+public:
+ SequenceTypeDescriptionImpl( const Reference< XTypeDescription > & xElementTD )
+ : _xElementTD( xElementTD )
+ {}
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+
+ // XIndirectTypeDescription
+ virtual Reference< XTypeDescription > SAL_CALL getReferencedType() throw(::com::sun::star::uno::RuntimeException);
+};
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass SequenceTypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return TypeClass_SEQUENCE;
+}
+//__________________________________________________________________________________________________
+OUString SequenceTypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return (OUString( RTL_CONSTASCII_USTRINGPARAM("[]") ) + _xElementTD->getName());
+}
+
+// XIndirectTypeDescription
+//__________________________________________________________________________________________________
+Reference< XTypeDescription > SequenceTypeDescriptionImpl::getReferencedType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _xElementTD;
+}
+
+//==================================================================================================
+class ArrayTypeDescriptionImpl
+ : public WeakImplHelper1< XArrayTypeDescription >
+{
+ Reference< XTypeDescription > _xElementTD;
+ Mutex _aDimensionMutex;
+ sal_Int32 _nDimensions;
+ Sequence< sal_Int32 > _seqDimensions;
+ OUString _sDimensions;
+
+ void initDimensions(const OUString& rSDimensions);
+public:
+ ArrayTypeDescriptionImpl( const Reference< XTypeDescription > & xElementTD,
+ sal_Int32 nDimensions, const OUString& rSDimensions )
+ : _xElementTD( xElementTD )
+ , _nDimensions( nDimensions )
+ , _seqDimensions( Sequence< sal_Int32 >(nDimensions) )
+ , _sDimensions( rSDimensions )
+ {
+ initDimensions( rSDimensions );
+ }
+ virtual ~ArrayTypeDescriptionImpl() {}
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+
+ // XArrayTypeDescription
+ virtual Reference< XTypeDescription > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getNumberOfDimensions() throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< sal_Int32 > SAL_CALL getDimensions() throw(::com::sun::star::uno::RuntimeException);
+};
+//__________________________________________________________________________________________________
+static sal_Int32 unicodeToInteger( sal_Int8 base, const sal_Unicode *s )
+{
+ sal_Int32 r = 0;
+ sal_Int32 negative = 0;
+
+ if (*s == '-')
+ {
+ negative = 1;
+ s++;
+ }
+ if (base == 8 && *s == '0')
+ s++;
+ else if (base == 16 && *s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
+ s += 2;
+
+ for (; *s; s++)
+ {
+ if (*s <= '9' && *s >= '0')
+ r = (r * base) + (*s - '0');
+ else if (base > 10 && *s <= 'f' && *s >= 'a')
+ r = (r * base) + (*s - 'a' + 10);
+ else if (base > 10 && *s <= 'F' && *s >= 'A')
+ r = (r * base) + (*s - 'A' + 10);
+ else
+ break;
+ }
+ if (negative) r *= -1;
+ return r;
+}
+//__________________________________________________________________________________________________
+void ArrayTypeDescriptionImpl::initDimensions(const OUString& rSDimensions)
+{
+ MutexGuard aGuard( _aDimensionMutex );
+
+ sal_Int32 * pDimensions = _seqDimensions.getArray();
+ OUString tmp(rSDimensions);
+ sal_Unicode* p = (sal_Unicode*)tmp.getStr()+1;
+ sal_Unicode* pOffset = p;
+ sal_Int32 len = tmp.getLength() - 1 ;
+ sal_Int32 i = 0;
+
+ while ( len > 0)
+ {
+ pOffset++;
+ if (*pOffset == ']')
+ {
+ *pOffset = '\0';
+ pOffset += 2;
+ len -= 3;
+ pDimensions[i++] = unicodeToInteger(10, p);
+ p = pOffset;
+ } else
+ len--;
+ }
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass ArrayTypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return TypeClass_ARRAY;
+}
+//__________________________________________________________________________________________________
+OUString ArrayTypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return (_xElementTD->getName() + _sDimensions);
+}
+
+// XArrayTypeDescription
+//__________________________________________________________________________________________________
+Reference< XTypeDescription > ArrayTypeDescriptionImpl::getType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _xElementTD;
+}
+
+//__________________________________________________________________________________________________
+sal_Int32 ArrayTypeDescriptionImpl::getNumberOfDimensions()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _nDimensions;
+}
+
+//__________________________________________________________________________________________________
+Sequence< sal_Int32 > ArrayTypeDescriptionImpl::getDimensions()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _seqDimensions;
+}
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+//__________________________________________________________________________________________________
+inline Any ManagerImpl::getSimpleType( const OUString & rName )
+{
+ Any aRet;
+
+ if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("string") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_STRING, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("long") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_LONG, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned long") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_LONG, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("boolean") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_BOOLEAN, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("char") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_CHAR, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("byte") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_BYTE, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("short") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_SHORT, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned short") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_SHORT, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("hyper") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_HYPER, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned hyper") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_HYPER, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("float") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_FLOAT, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("double") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_DOUBLE, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("any") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_ANY, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("void") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_VOID, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("type") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_TYPE, rName ) );
+
+ return aRet;
+}
+
+namespace {
+
+Reference< XTypeDescription > resolveTypedefs(
+ Reference< XTypeDescription > const & type)
+{
+ Reference< XTypeDescription > resolved(type);
+ while (resolved->getTypeClass() == TypeClass_TYPEDEF) {
+ resolved = Reference< XIndirectTypeDescription >(
+ type, UNO_QUERY_THROW)->getReferencedType();
+ }
+ return resolved;
+}
+
+bool isNonVoidNonExceptionType(Reference< XTypeDescription > const & type) {
+ switch (type->getTypeClass()) {
+ case TypeClass_BOOLEAN:
+ case TypeClass_BYTE:
+ case TypeClass_SHORT:
+ case TypeClass_UNSIGNED_SHORT:
+ case TypeClass_LONG:
+ case TypeClass_UNSIGNED_LONG:
+ case TypeClass_HYPER:
+ case TypeClass_UNSIGNED_HYPER:
+ case TypeClass_FLOAT:
+ case TypeClass_DOUBLE:
+ case TypeClass_CHAR:
+ case TypeClass_STRING:
+ case TypeClass_TYPE:
+ case TypeClass_ANY:
+ case TypeClass_SEQUENCE:
+ case TypeClass_ENUM:
+ case TypeClass_STRUCT:
+ case TypeClass_INTERFACE:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+class InstantiatedStruct: public WeakImplHelper1< XStructTypeDescription > {
+public:
+ InstantiatedStruct(
+ Reference< XStructTypeDescription > const & structType,
+ std::vector< Reference< XTypeDescription > > const & arguments);
+
+ virtual TypeClass SAL_CALL getTypeClass() throw (RuntimeException)
+ { return TypeClass_STRUCT; }
+
+ virtual OUString SAL_CALL getName() throw (RuntimeException);
+
+ virtual Reference< XTypeDescription > SAL_CALL getBaseType()
+ throw (RuntimeException)
+ { return m_struct->getBaseType(); }
+
+ virtual Sequence< Reference< XTypeDescription > > SAL_CALL getMemberTypes()
+ throw (RuntimeException);
+
+ virtual Sequence< OUString > SAL_CALL getMemberNames()
+ throw (RuntimeException)
+ { return m_struct->getMemberNames(); }
+
+ virtual Sequence< OUString > SAL_CALL getTypeParameters()
+ throw (RuntimeException)
+ { return Sequence< OUString >(); }
+
+ virtual Sequence< Reference< XTypeDescription > > SAL_CALL
+ getTypeArguments() throw (RuntimeException)
+ { return m_arguments; }
+
+private:
+ Reference< XStructTypeDescription > m_struct;
+ Sequence< Reference< XTypeDescription > > m_arguments;
+};
+
+InstantiatedStruct::InstantiatedStruct(
+ Reference< XStructTypeDescription > const & structType,
+ std::vector< Reference< XTypeDescription > > const & arguments):
+ m_struct(structType),
+ m_arguments(static_cast< sal_Int32 >(arguments.size()))
+{
+ for (std::vector< Reference< XTypeDescription > >::size_type i = 0;
+ i < arguments.size(); ++i)
+ {
+ m_arguments[static_cast< sal_Int32 >(i)] = arguments[i];
+ }
+}
+
+OUString InstantiatedStruct::getName() throw (RuntimeException) {
+ OUStringBuffer buf(m_struct->getName());
+ buf.append(static_cast< sal_Unicode >('<'));
+ for (sal_Int32 i = 0; i < m_arguments.getLength(); ++i) {
+ if (i != 0) {
+ buf.append(static_cast< sal_Unicode >(','));
+ }
+ buf.append(m_arguments[i]->getName());
+ }
+ buf.append(static_cast< sal_Unicode >('>'));
+ return buf.makeStringAndClear();
+}
+
+Sequence< Reference< XTypeDescription > > InstantiatedStruct::getMemberTypes()
+ throw (RuntimeException)
+{
+ Sequence< Reference< XTypeDescription > > types(m_struct->getMemberTypes());
+ for (sal_Int32 i = 0; i < types.getLength(); ++i) {
+ if (types[i]->getTypeClass() == TypeClass_UNKNOWN) {
+ Sequence< OUString > parameters(m_struct->getTypeParameters());
+ OSL_ASSERT(parameters.getLength() == m_arguments.getLength());
+ for (sal_Int32 j = 0; j < parameters.getLength(); ++j) {
+ if (parameters[j] == types[i]->getName()) {
+ types[i] = m_arguments[j];
+ break;
+ }
+ }
+ }
+ }
+ return types;
+}
+
+}
+
+Reference< XTypeDescription > ManagerImpl::getInstantiatedStruct(
+ OUString const & name)
+{
+ sal_Int32 i = name.indexOf('<');
+ OSL_ASSERT(i >= 0);
+ Reference< XStructTypeDescription > structType(
+ getByHierarchicalName(name.copy(0, i)), UNO_QUERY);
+ std::vector< Reference< XTypeDescription > > args;
+ bool good = structType.is();
+ if (good) {
+ do {
+ ++i; // skip '<' or ','
+ sal_Int32 j = i;
+ for (sal_Int32 level = 0; j != name.getLength(); ++j) {
+ sal_Unicode c = name[j];
+ if (c == ',') {
+ if (level == 0) {
+ break;
+ }
+ } else if (c == '<') {
+ ++level;
+ } else if (c == '>') {
+ if (level == 0) {
+ break;
+ }
+ --level;
+ }
+ }
+ if (j != name.getLength()) {
+ Reference< XTypeDescription > type(
+ getByHierarchicalName(name.copy(i, j - i)), UNO_QUERY);
+ if (isNonVoidNonExceptionType(resolveTypedefs(type))) {
+ args.push_back(type);
+ } else {
+ good = false;
+ break;
+ }
+ }
+ i = j;
+ } while (i != name.getLength() && name[i] != '>');
+ good = good && i == name.getLength() - 1
+ && name[i] == '>' && !args.empty();
+ }
+ // args.size() cannot exceed SAL_MAX_INT32, as each argument consumes at
+ // least one position within an rtl::OUString (which is no longer than
+ // SAL_MAX_INT32):
+ if (!good
+ || (args.size()
+ != sal::static_int_cast< sal_uInt32 >(
+ structType->getTypeParameters().getLength())))
+ {
+ throw NoSuchElementException(name, static_cast< OWeakObject * >(this));
+ }
+ return new InstantiatedStruct(structType, args);
+}
+
+// XHierarchicalNameAccess
+//__________________________________________________________________________________________________
+Any ManagerImpl::getByHierarchicalName( const OUString & rName )
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
+{
+ Any aRet;
+ if (_bCaching)
+ aRet = _aElements.getValue( rName );
+ if (rName.getLength() && !aRet.hasValue())
+ {
+ sal_Int32 nIndex;
+ if (rName[0] == '[') // test for sequence
+ {
+ Reference< XTypeDescription > xElemType(
+ getByHierarchicalName( rName.copy( 2 ) ),
+ UNO_QUERY_THROW );
+ aRet <<= Reference< XTypeDescription >(
+ new SequenceTypeDescriptionImpl( xElemType ) );
+ }
+ else if (rName[rName.getLength()-1] == ']') // test for array
+ {
+ sal_Int32 nIndex2 = 0, nTokens = 0;
+ do { rName.getToken( 0, '[', nIndex2 ); nTokens++; } while( nIndex2 != -1 );
+ sal_Int32 nDims = nTokens - 1;
+ sal_Int32 dimOffset = rName.indexOf('[');
+ Reference< XTypeDescription > xElemType(
+ getByHierarchicalName( rName.copy( 0, dimOffset ) ),
+ UNO_QUERY_THROW );
+ aRet <<= Reference< XTypeDescription >(
+ new ArrayTypeDescriptionImpl(
+ xElemType, nDims, rName.copy(dimOffset) ) );
+ }
+ // test for interface member names:
+ else if ((nIndex = rName.indexOf( ':' )) >= 0)
+ {
+ Reference< XInterfaceTypeDescription > xIfaceTD(
+ getByHierarchicalName( rName.copy( 0, nIndex ) ),
+ UNO_QUERY_THROW );
+ const Sequence< Reference< XInterfaceMemberTypeDescription > > &
+ rMembers = xIfaceTD->getMembers();
+ const Reference< XInterfaceMemberTypeDescription > * pMembers =
+ rMembers.getConstArray();
+
+ for ( sal_Int32 nPos = rMembers.getLength(); nPos--; )
+ {
+ if (rName == pMembers[nPos]->getName())
+ {
+ aRet <<= Reference< XTypeDescription >(
+ pMembers[nPos], UNO_QUERY_THROW );
+ break;
+ }
+ }
+ if (! aRet.hasValue())
+ {
+ // member not found:
+ throw NoSuchElementException(
+ rName, static_cast< OWeakObject * >(this) );
+ }
+ }
+ // test for instantiated polymorphic struct types:
+ else if (rName.indexOf('<') >= 0)
+ {
+ aRet <<= getInstantiatedStruct(rName);
+ }
+ else if (rName.indexOf( '.' ) < 0) // test for simple/ build in types
+ {
+ aRet = getSimpleType( rName );
+ }
+
+ if (! aRet.hasValue())
+ {
+ // last, try callback chain
+ for ( ProviderVector::const_iterator iPos( _aProviders.begin() );
+ iPos != _aProviders.end(); ++iPos )
+ {
+ try
+ {
+ if ((aRet = (*iPos)->getByHierarchicalName(
+ rName )).hasValue())
+ {
+ break;
+ }
+ }
+ catch (NoSuchElementException &)
+ {
+ }
+ }
+ }
+
+ // update cache
+ if (_bCaching && aRet.hasValue())
+ _aElements.setValue( rName, aRet );
+ }
+
+ if (! aRet.hasValue())
+ {
+ throw NoSuchElementException(
+ rName, static_cast< OWeakObject * >(this) );
+ }
+ return aRet;
+}
+//__________________________________________________________________________________________________
+sal_Bool ManagerImpl::hasByHierarchicalName( const OUString & rName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ try
+ {
+ return getByHierarchicalName( rName ).hasValue();
+ }
+ catch (NoSuchElementException &)
+ {
+ }
+ return sal_False;
+}
+}
+
+namespace stoc_bootstrap
+{
+//==================================================================================================
+Reference< XInterface > SAL_CALL ManagerImpl_create(
+ Reference< XComponentContext > const & xContext )
+ SAL_THROW( (::com::sun::star::uno::Exception) )
+{
+ sal_Int32 nCacheSize = CACHE_SIZE;
+ if (xContext.is()) {
+ xContext->getValueByName(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "/implementations/" IMPLNAME "/CacheSize"))) >>=
+ nCacheSize;
+ }
+
+ return Reference< XInterface >( *new stoc_tdmgr::ManagerImpl( xContext, nCacheSize ) );
+}
+
+}
+
diff --git a/stoc/source/tdmanager/tdmgr_check.cxx b/stoc/source/tdmanager/tdmgr_check.cxx
new file mode 100644
index 000000000000..0a19403532bf
--- /dev/null
+++ b/stoc/source/tdmanager/tdmgr_check.cxx
@@ -0,0 +1,556 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "tdmgr_common.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "typelib/typedescription.h"
+#include "com/sun/star/beans/PropertyAttribute.hpp"
+#include "com/sun/star/reflection/XConstantsTypeDescription.hpp"
+#include "com/sun/star/reflection/XIndirectTypeDescription.hpp"
+#include "com/sun/star/reflection/XEnumTypeDescription.hpp"
+#include "com/sun/star/reflection/XStructTypeDescription.hpp"
+#include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
+#include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp"
+#include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp"
+#include "com/sun/star/reflection/XServiceTypeDescription2.hpp"
+#include "com/sun/star/reflection/XSingletonTypeDescription2.hpp"
+
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::stoc_tdmgr;
+
+namespace {
+
+OUString getTypeClassName( TypeClass tc )
+{
+ typelib_EnumTypeDescription * typeDescr = 0;
+ OUString name = OUSTR("com.sun.star.uno.TypeClass");
+ typelib_typedescription_getByName(
+ reinterpret_cast<typelib_TypeDescription **>(&typeDescr), name.pData );
+ OSL_ASSERT( typeDescr != 0 );
+ if (typeDescr == 0)
+ return OUSTR("Cannot get type description of ") + name;
+ typelib_typedescription_complete(
+ reinterpret_cast<typelib_TypeDescription **>(&typeDescr) );
+
+ sal_Int32 const * pValues = typeDescr->pEnumValues;
+ sal_Int32 nPos = typeDescr->nEnumValues;
+ while (nPos--)
+ {
+ if (pValues[ nPos ] == (sal_Int32) tc)
+ break;
+ }
+ if (nPos >= 0)
+ name = typeDescr->ppEnumNames[ nPos ];
+ else
+ name = OUSTR("unknown TypeClass value: ") +
+ OUString::valueOf( (sal_Int32) tc );
+
+ typelib_typedescription_release(
+ reinterpret_cast<typelib_TypeDescription *>(typeDescr) );
+ return name;
+}
+
+OUString getPropertyFlagsAsString( sal_Int16 attributes )
+{
+ OUStringBuffer buf;
+ if ((attributes & beans::PropertyAttribute::MAYBEVOID) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("MAYBEVOID, ") );
+ if ((attributes & beans::PropertyAttribute::BOUND) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("BOUND, ") );
+ if ((attributes & beans::PropertyAttribute::CONSTRAINED) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("CONSTRAINED, ") );
+ if ((attributes & beans::PropertyAttribute::TRANSIENT) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("TRANSIENT, ") );
+ if ((attributes & beans::PropertyAttribute::READONLY) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("READONLY, ") );
+ if ((attributes & beans::PropertyAttribute::MAYBEAMBIGUOUS) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("MAYBEAMBIGUOUS, ") );
+ if ((attributes & beans::PropertyAttribute::MAYBEDEFAULT) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("MAYBEDEFAULT, ") );
+ if ((attributes & beans::PropertyAttribute::REMOVEABLE) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("REMOVEABLE, ") );
+ if ((attributes & beans::PropertyAttribute::OPTIONAL) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("OPTIONAL") );
+ else if (buf.getLength() > 0)
+ buf.setLength( buf.getLength() - 2 ); // truncate ", "
+ return buf.makeStringAndClear();
+}
+
+void typeError( OUString const & msg, OUString const & context )
+{
+ OUStringBuffer buf;
+ if (context.getLength() > 0) {
+ buf.append( static_cast<sal_Unicode>('[') );
+ buf.append( context );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
+ }
+ buf.append( msg );
+ throw IncompatibleTypeException( buf.makeStringAndClear() );
+}
+
+template<typename T>
+void checkSeq( Sequence< Reference<T> > const & newTypes,
+ Sequence< Reference<T> > const & existingTypes,
+ OUString const & context,
+ bool optionalMode = false )
+{
+ sal_Int32 len = newTypes.getLength();
+ if (len != existingTypes.getLength())
+ {
+ if (!optionalMode || len < newTypes.getLength())
+ typeError( OUSTR("Different number of types!"), context );
+ len = existingTypes.getLength();
+ }
+
+ Reference<T> const * pNewTypes = newTypes.getConstArray();
+ Reference<T> const * pExistingTypes = existingTypes.getConstArray();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ OUStringBuffer buf;
+ buf.append( context );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", position ") );
+ buf.append( pos );
+ check( pNewTypes[pos].get(), pExistingTypes[pos].get(),
+ buf.makeStringAndClear() );
+ }
+}
+
+void checkEnum(
+ Reference<reflection::XEnumTypeDescription> const & xNewTD,
+ Reference<reflection::XEnumTypeDescription> const & xExistingTD )
+{
+ if (xNewTD->getEnumNames() != xExistingTD->getEnumNames())
+ typeError( OUSTR("ENUM names don't match!"), xNewTD->getName() );
+ if (xNewTD->getEnumValues() != xExistingTD->getEnumValues())
+ typeError( OUSTR("ENUM values don't match!"), xNewTD->getName() );
+}
+
+void checkStruct(
+ Reference<reflection::XCompoundTypeDescription> const & xNewTD,
+ Reference<reflection::XCompoundTypeDescription> const & xExistingTD )
+{
+ check( xNewTD->getBaseType(), xExistingTD->getBaseType(),
+ xNewTD->getName() + OUSTR(", base type") );
+ checkSeq( xNewTD->getMemberTypes(), xExistingTD->getMemberTypes(),
+ xNewTD->getName() + OUSTR(", member types") );
+
+ if (xNewTD->getMemberNames() != xExistingTD->getMemberNames())
+ typeError( OUSTR("Different member names!"), xNewTD->getName() );
+
+ if (xNewTD->getTypeClass() == TypeClass_STRUCT)
+ {
+ Reference<reflection::XStructTypeDescription> xNewStructTD(
+ xNewTD, UNO_QUERY );
+ Reference<reflection::XStructTypeDescription> xExistingStructTD(
+ xExistingTD, UNO_QUERY );
+ if (xNewStructTD.is() && xExistingStructTD.is())
+ {
+ if (xNewStructTD->getTypeParameters() !=
+ xExistingStructTD->getTypeParameters())
+ typeError( OUSTR("Different type parameters of instantiated "
+ "polymorphic STRUCT!"), xNewTD->getName() );
+ checkSeq( xNewStructTD->getTypeArguments(),
+ xExistingStructTD->getTypeArguments(),
+ xNewTD->getName() + OUSTR(", argument types") );
+ }
+ else if (xNewStructTD.is() || xExistingStructTD.is())
+ typeError( OUSTR("Mixing polymorphic STRUCT types "
+ "with non-polymorphic!"), xNewTD->getName() );
+ }
+}
+
+void checkInterface(
+ Reference<reflection::XInterfaceTypeDescription2> const & xNewTD,
+ Reference<reflection::XInterfaceTypeDescription2> const & xExistingTD )
+{
+ checkSeq( xNewTD->getBaseTypes(), xExistingTD->getBaseTypes(),
+ xNewTD->getName() + OUSTR(", base types") );
+ checkSeq(xNewTD->getOptionalBaseTypes(),xExistingTD->getOptionalBaseTypes(),
+ xNewTD->getName() + OUSTR(", optional base types") );
+ checkSeq( xNewTD->getMembers(), xExistingTD->getMembers(),
+ xNewTD->getName() + OUSTR(", members") );
+}
+
+void checkRestParam( Reference<reflection::XParameter> const & xNewParam,
+ Reference<reflection::XParameter> const & xExistingParam,
+ OUString const & context )
+{
+ if (xNewParam->isRestParameter() != xExistingParam->isRestParameter())
+ typeError( OUSTR("Different ... parameters specified!"), context );
+}
+
+void checkRestParam( Reference<reflection::XMethodParameter> const &,
+ Reference<reflection::XMethodParameter> const &,
+ OUString const & )
+{
+}
+
+template<typename T>
+void checkParameters( Sequence< Reference<T> > const & newParams,
+ Sequence< Reference<T> > const & existingParams,
+ OUString const & context_ )
+{
+ sal_Int32 len = newParams.getLength();
+ if (len != existingParams.getLength())
+ typeError( OUSTR("Different number of parameters!"), context_ );
+ Reference<T> const * pNewParams = newParams.getConstArray();
+ Reference<T> const * pExistingParams = existingParams.getConstArray();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ Reference<T> const & xNewParam = pNewParams[pos];
+ Reference<T> const & xExistingParam = pExistingParams[pos];
+
+ OUStringBuffer buf;
+ buf.append( context_ );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", parameter ") );
+ buf.append( pos );
+ OSL_ASSERT( pos == xNewParam->getPosition() &&
+ pos == xExistingParam->getPosition() );
+ OUString context( buf.makeStringAndClear() );
+
+ if (xNewParam->getName() != xExistingParam->getName())
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Name differs: ") );
+ buf.append( xNewParam->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
+ buf.append( xExistingParam->getName() );
+ typeError( buf.makeStringAndClear(), context );
+ }
+ check( xNewParam->getType(), xExistingParam->getType(), context );
+
+ if (xNewParam->isIn() != xExistingParam->isIn())
+ typeError( OUSTR("IN attribute differs!"), context );
+ if (xNewParam->isOut() != xExistingParam->isOut())
+ typeError( OUSTR("OUT attribute differs!"), context );
+ checkRestParam( xNewParam, xExistingParam, context );
+ }
+}
+
+static void checkMethod(
+ Reference<reflection::XInterfaceMethodTypeDescription> const & xNewTD,
+ Reference<reflection::XInterfaceMethodTypeDescription> const & xExistingTD )
+{
+ check( xNewTD->getReturnType(), xExistingTD->getReturnType(),
+ xNewTD->getName() );
+
+ if (xNewTD->isOneway() != xExistingTD->isOneway())
+ typeError( OUSTR("Methods have differing OneWay attribute!"),
+ xNewTD->getName() );
+
+ checkParameters( xNewTD->getParameters(), xExistingTD->getParameters(),
+ xNewTD->getName() );
+
+ checkSeq( xNewTD->getExceptions(), xExistingTD->getExceptions(),
+ xNewTD->getName() + OUSTR(", declared exceptions") );
+}
+
+void checkAttribute(
+ Reference<reflection::XInterfaceAttributeTypeDescription2> const & xNewTD,
+ Reference<reflection::XInterfaceAttributeTypeDescription2>
+ const & xExistingTD )
+{
+ if (xNewTD->isReadOnly() != xExistingTD->isReadOnly())
+ typeError( OUSTR("ReadOnly attribute differs!"), xNewTD->getName() );
+
+ check( xNewTD->getType(), xExistingTD->getType(),
+ xNewTD->getName() + OUSTR(", attribute type") );
+
+ if (xNewTD->isBound() != xExistingTD->isBound())
+ typeError( OUSTR("Bound attribute differs!"), xNewTD->getName() );
+
+ checkSeq( xNewTD->getGetExceptions(), xExistingTD->getGetExceptions(),
+ xNewTD->getName() + OUSTR(", getter exceptions") );
+ checkSeq( xNewTD->getSetExceptions(), xExistingTD->getSetExceptions(),
+ xNewTD->getName() + OUSTR(", setter exceptions") );
+}
+
+void checkProperty(
+ Reference<reflection::XPropertyTypeDescription> const & xNewTD,
+ Reference<reflection::XPropertyTypeDescription> const & xExistingTD )
+{
+ if (xNewTD->getPropertyFlags() != xExistingTD->getPropertyFlags())
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "Different set of property flags: { ") );
+ buf.append( getPropertyFlagsAsString(
+ xNewTD->getPropertyFlags() ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" } (new), { ") );
+ buf.append( getPropertyFlagsAsString(
+ xExistingTD->getPropertyFlags() ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" } (existing)!") );
+ typeError( buf.makeStringAndClear(), xNewTD->getName() );
+ }
+
+ check( xNewTD->getPropertyTypeDescription(),
+ xExistingTD->getPropertyTypeDescription(),
+ xNewTD->getName() );
+}
+
+void checkSingleton(
+ Reference<reflection::XSingletonTypeDescription2> const & xNewTD,
+ Reference<reflection::XSingletonTypeDescription2> const & xExistingTD )
+{
+ sal_Bool ifaceBased = xNewTD->isInterfaceBased();
+ if (ifaceBased != xExistingTD->isInterfaceBased())
+ typeError(
+ OUSTR("Mixing interface and NON-interface based singletons!"),
+ xNewTD->getName() );
+ if (ifaceBased)
+ check( xNewTD->getInterface(), xExistingTD->getInterface(),
+ xNewTD->getName() );
+ else
+ check( xNewTD->getService().get(), xExistingTD->getService().get(),
+ xNewTD->getName() );
+}
+
+void checkService(
+ Reference<reflection::XServiceTypeDescription2> const & xNewTD,
+ Reference<reflection::XServiceTypeDescription2> const & xExistingTD )
+{
+ sal_Bool singleIfaceBased = xNewTD->isSingleInterfaceBased();
+ if (singleIfaceBased != xExistingTD->isSingleInterfaceBased())
+ typeError( OUSTR("Mixing interface and NON-interface based services!"),
+ xNewTD->getName() );
+ if (singleIfaceBased)
+ {
+ check( xNewTD->getInterface(), xExistingTD->getInterface(),
+ xNewTD->getName() );
+ Sequence< Reference<reflection::XServiceConstructorDescription> >
+ newCtors( xNewTD->getConstructors() );
+ Sequence< Reference<reflection::XServiceConstructorDescription> >
+ existingCtors( xExistingTD->getConstructors() );
+ sal_Int32 len = newCtors.getLength();
+ if (len != existingCtors.getLength())
+ typeError( OUSTR("Different number of service constructors!"),
+ xNewTD->getName() );
+ Reference<reflection::XServiceConstructorDescription> const *
+ pNewCtors = newCtors.getConstArray();
+ Reference<reflection::XServiceConstructorDescription> const *
+ pExistingCtors = existingCtors.getConstArray();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ Reference<reflection::XServiceConstructorDescription> const &
+ xNewCtor = pNewCtors[pos];
+ Reference<reflection::XServiceConstructorDescription> const &
+ xExistingCtor = pExistingCtors[pos];
+
+ if (xNewCtor->getName() != xExistingCtor->getName())
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "Different constructor names: ") );
+ buf.append( xNewCtor->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (new), ") );
+ buf.append( xExistingCtor->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (existing)!") );
+ typeError( buf.makeStringAndClear(), xNewTD->getName() );
+ }
+
+ OUStringBuffer buf;
+ buf.append( xNewTD->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", constructor ") );
+ buf.append( xNewCtor->getName() );
+ OUString context( buf.makeStringAndClear() );
+ checkParameters( xNewCtor->getParameters(),
+ xExistingCtor->getParameters(),
+ context );
+ checkSeq( xNewCtor->getExceptions(), xExistingCtor->getExceptions(),
+ context + OUSTR(", exceptions") );
+ }
+ }
+ else // old-style service descriptions:
+ {
+ checkSeq( xNewTD->getMandatoryServices(),
+ xExistingTD->getMandatoryServices(),
+ xNewTD->getName() + OUSTR(", mandatory services") );
+ checkSeq( xNewTD->getOptionalServices(),
+ xExistingTD->getOptionalServices(),
+ xNewTD->getName() + OUSTR(", optional services"),
+ true /* optionalMode */ );
+ checkSeq( xNewTD->getMandatoryInterfaces(),
+ xExistingTD->getMandatoryInterfaces(),
+ xNewTD->getName() + OUSTR(", mandatory interfaces") );
+ checkSeq( xNewTD->getOptionalInterfaces(),
+ xExistingTD->getOptionalInterfaces(),
+ xNewTD->getName() + OUSTR(", optional interfaces"),
+ true /* optionalMode */ );
+
+ Sequence< Reference<reflection::XPropertyTypeDescription> >
+ newProperties( xNewTD->getProperties() );
+ Sequence< Reference<reflection::XPropertyTypeDescription> >
+ existingProperties( xExistingTD->getProperties() );
+ checkSeq( newProperties, existingProperties,
+ xNewTD->getName() + OUSTR(", properties"),
+ true /* optionalMode */ );
+ if (newProperties.getLength() > existingProperties.getLength())
+ {
+ // check whether all added properties are OPTIONAL:
+ Reference<reflection::XPropertyTypeDescription> const *
+ pNewProperties = newProperties.getConstArray();
+ for ( sal_Int32 pos = existingProperties.getLength() + 1;
+ pos < newProperties.getLength(); ++pos )
+ {
+ if ((pNewProperties[pos]->getPropertyFlags() &
+ beans::PropertyAttribute::OPTIONAL) == 0)
+ typeError( OUSTR("New property is not OPTIONAL!"),
+ pNewProperties[pos]->getName() );
+ }
+ }
+ }
+}
+
+}
+
+namespace stoc_tdmgr {
+
+void check( Reference<reflection::XTypeDescription> const & xNewTD,
+ Reference<reflection::XTypeDescription> const & xExistingTD,
+ OUString const & context )
+{
+ if (xNewTD == xExistingTD)
+ return;
+ if (xNewTD->getName() != xExistingTD->getName())
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Different type names: ") );
+ buf.append( xNewTD->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (new), ") );
+ buf.append( xExistingTD->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (existing)!") );
+ typeError( buf.makeStringAndClear(), context );
+ }
+
+ TypeClass tc = xNewTD->getTypeClass();
+ if (tc != xExistingTD->getTypeClass())
+ {
+ OUStringBuffer buf;
+ buf.append( xNewTD->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ " has different type classes: ") );
+ buf.append( getTypeClassName( tc ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (new), ") );
+ buf.append( getTypeClassName( xExistingTD->getTypeClass() ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (existing)!") );
+ typeError( buf.makeStringAndClear(), context );
+ }
+
+ switch (tc)
+ {
+ case TypeClass_ENUM:
+ checkEnum( Reference<reflection::XEnumTypeDescription>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XEnumTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ case TypeClass_TYPEDEF:
+ case TypeClass_SEQUENCE:
+ check( Reference<reflection::XIndirectTypeDescription>(
+ xNewTD, UNO_QUERY_THROW )->getReferencedType(),
+ Reference<reflection::XIndirectTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW )->getReferencedType() );
+ break;
+
+ case TypeClass_STRUCT:
+ case TypeClass_EXCEPTION:
+ checkStruct( Reference<reflection::XCompoundTypeDescription>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XCompoundTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ case TypeClass_INTERFACE:
+ checkInterface( Reference<reflection::XInterfaceTypeDescription2>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XInterfaceTypeDescription2>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ case TypeClass_SERVICE:
+ checkService( Reference<reflection::XServiceTypeDescription2>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XServiceTypeDescription2>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ case TypeClass_INTERFACE_METHOD:
+ checkMethod( Reference<reflection::XInterfaceMethodTypeDescription>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XInterfaceMethodTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+ case TypeClass_INTERFACE_ATTRIBUTE:
+ checkAttribute(
+ Reference<reflection::XInterfaceAttributeTypeDescription2>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XInterfaceAttributeTypeDescription2>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ case TypeClass_PROPERTY:
+ checkProperty( Reference<reflection::XPropertyTypeDescription>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XPropertyTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ case TypeClass_CONSTANT:
+ if (Reference<reflection::XConstantTypeDescription>(
+ xNewTD, UNO_QUERY_THROW )->getConstantValue() !=
+ Reference<reflection::XConstantTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW )->getConstantValue())
+ typeError( OUSTR("Different constant value!"), xNewTD->getName() );
+ break;
+ case TypeClass_CONSTANTS:
+ checkSeq( Reference<reflection::XConstantsTypeDescription>(
+ xNewTD, UNO_QUERY_THROW )->getConstants(),
+ Reference<reflection::XConstantsTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW )->getConstants(),
+ xNewTD->getName() );
+ break;
+
+ case TypeClass_SINGLETON:
+ checkSingleton( Reference<reflection::XSingletonTypeDescription2>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XSingletonTypeDescription2>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ default:
+ break;
+ }
+}
+
+}
diff --git a/stoc/source/tdmanager/tdmgr_common.hxx b/stoc/source/tdmanager/tdmgr_common.hxx
new file mode 100644
index 000000000000..5d640e99f919
--- /dev/null
+++ b/stoc/source/tdmanager/tdmgr_common.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STOC_TDMGR_COMMON_HXX
+#define _STOC_TDMGR_COMMON_HXX
+
+#include <rtl/unload.h>
+
+#include "com/sun/star/reflection/XTypeDescription.hpp"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+#define ARLEN(x) (sizeof (x) / sizeof *(x))
+
+
+namespace css = ::com::sun::star;
+
+namespace stoc_tdmgr
+{
+ extern rtl_StandardModuleCount g_moduleCount;
+
+struct IncompatibleTypeException
+{
+ ::rtl::OUString m_cause;
+ IncompatibleTypeException( ::rtl::OUString const & cause )
+ : m_cause( cause ) {}
+};
+
+void check(
+ css::uno::Reference<css::reflection::XTypeDescription> const & xNewTD,
+ css::uno::Reference<css::reflection::XTypeDescription> const & xExistingTD,
+ ::rtl::OUString const & context = ::rtl::OUString() );
+/* throw (css::uno::RuntimeException, IncompatibleTypeException) */
+
+} // namespace stoc_tdmgr
+
+#endif /* _STOC_TDMGR_COMMON_HXX */
diff --git a/stoc/source/tdmanager/tdmgr_tdenumeration.cxx b/stoc/source/tdmanager/tdmgr_tdenumeration.cxx
new file mode 100644
index 000000000000..c1815c932db5
--- /dev/null
+++ b/stoc/source/tdmanager/tdmgr_tdenumeration.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/diagnose.h>
+#include "tdmgr_common.hxx"
+#include "tdmgr_tdenumeration.hxx"
+
+using namespace com::sun::star;
+
+extern rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_tdmgr
+{
+
+//=========================================================================
+//=========================================================================
+//
+// TypeDescriptionEnumerationImpl Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+TypeDescriptionEnumerationImpl::TypeDescriptionEnumerationImpl(
+ const rtl::OUString & rModuleName,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::uno::TypeClass > & rTypes,
+ com::sun::star::reflection::TypeDescriptionSearchDepth eDepth,
+ const TDEnumerationAccessStack & rTDEAS )
+: m_aModuleName( rModuleName ),
+ m_aTypes( rTypes ),
+ m_eDepth( eDepth ),
+ m_aChildren( rTDEAS )
+{
+ ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt );
+}
+
+//=========================================================================
+// virtual
+TypeDescriptionEnumerationImpl::~TypeDescriptionEnumerationImpl()
+{
+ ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt );
+}
+
+//=========================================================================
+//
+// XEnumeration (base of XTypeDescriptionEnumeration) methods
+//
+//=========================================================================
+
+// virtual
+sal_Bool SAL_CALL TypeDescriptionEnumerationImpl::hasMoreElements()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum
+ = queryCurrentChildEnumeration();
+ if ( xEnum.is() )
+ return xEnum->hasMoreElements();
+
+ return sal_False;
+}
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL TypeDescriptionEnumerationImpl::nextElement()
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum
+ = queryCurrentChildEnumeration();
+ if ( xEnum.is() )
+ return xEnum->nextElement();
+
+ throw container::NoSuchElementException(
+ rtl::OUString::createFromAscii(
+ "No further elements in enumeration!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+}
+
+//=========================================================================
+//
+// XTypeDescriptionEnumeration methods
+//
+//=========================================================================
+
+// virtual
+uno::Reference< reflection::XTypeDescription > SAL_CALL
+TypeDescriptionEnumerationImpl::nextTypeDescription()
+ throw ( container::NoSuchElementException,
+ uno::RuntimeException )
+{
+ uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum
+ = queryCurrentChildEnumeration();
+ if ( xEnum.is() )
+ return xEnum->nextTypeDescription();
+
+ throw container::NoSuchElementException(
+ rtl::OUString::createFromAscii(
+ "No further elements in enumeration!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+}
+
+//=========================================================================
+uno::Reference< reflection::XTypeDescriptionEnumeration >
+TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ for (;;)
+ {
+ if ( m_xEnum.is() )
+ {
+ if ( m_xEnum->hasMoreElements() )
+ {
+ return m_xEnum;
+ }
+ else
+ {
+ // Forget about enumeration without further elements. Try next.
+ m_xEnum.clear();
+ }
+ }
+
+ // Note: m_xEnum is always null here.
+
+ if ( m_aChildren.empty() )
+ {
+ // No child enumerations left.
+ return m_xEnum;
+ }
+
+ try
+ {
+ m_xEnum =
+ m_aChildren.top()->createTypeDescriptionEnumeration(
+ m_aModuleName, m_aTypes, m_eDepth );
+ }
+ catch ( reflection::NoSuchTypeNameException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration "
+ "- Caught NoSuchTypeNameException!" );
+ }
+ catch ( reflection::InvalidTypeNameException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration "
+ "- Caught InvalidTypeNameException!" );
+ }
+
+ // We're done with this enumeration access in any case (Either
+ // enumeration was successfully created or creation failed for some
+ // reason).
+ m_aChildren.pop();
+ }
+
+ // unreachable
+}
+
+} // namespace stoc_tdmgr
+
diff --git a/stoc/source/tdmanager/tdmgr_tdenumeration.hxx b/stoc/source/tdmanager/tdmgr_tdenumeration.hxx
new file mode 100644
index 000000000000..1b383af538c1
--- /dev/null
+++ b/stoc/source/tdmanager/tdmgr_tdenumeration.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STOC_TDMGR_TDENUMERATION_HXX
+#define _STOC_TDMGR_TDENUMERATION_HXX
+
+#include <stack>
+#include <osl/mutex.hxx>
+#include <com/sun/star/reflection/XTypeDescriptionEnumeration.hpp>
+#include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+namespace stoc_tdmgr
+{
+
+typedef std::stack< com::sun::star::uno::Reference<
+ com::sun::star::reflection::XTypeDescriptionEnumerationAccess > >
+ TDEnumerationAccessStack;
+
+class TypeDescriptionEnumerationImpl
+ : public cppu::WeakImplHelper1<
+ com::sun::star::reflection::XTypeDescriptionEnumeration >
+{
+public:
+ TypeDescriptionEnumerationImpl(
+ const rtl::OUString & rModuleName,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::uno::TypeClass > & rTypes,
+ com::sun::star::reflection::TypeDescriptionSearchDepth eDepth,
+ const TDEnumerationAccessStack & rTDEAS );
+ virtual ~TypeDescriptionEnumerationImpl();
+
+ // XEnumeration (base of XTypeDescriptionEnumeration)
+ virtual sal_Bool SAL_CALL hasMoreElements()
+ throw ( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Any SAL_CALL nextElement()
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // XTypeDescriptionEnumeration
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XTypeDescription > SAL_CALL
+ nextTypeDescription()
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException );
+
+private:
+ com::sun::star::uno::Reference<
+ com::sun::star::reflection::XTypeDescriptionEnumeration >
+ queryCurrentChildEnumeration();
+
+ osl::Mutex m_aMutex;
+ rtl::OUString m_aModuleName;
+ com::sun::star::uno::Sequence< com::sun::star::uno::TypeClass > m_aTypes;
+ com::sun::star::reflection::TypeDescriptionSearchDepth m_eDepth;
+ TDEnumerationAccessStack m_aChildren;
+ com::sun::star::uno::Reference<
+ com::sun::star::reflection::XTypeDescriptionEnumeration > m_xEnum;
+};
+
+} // namespace stoc_tdmgr
+
+#endif /* _STOC_TDMGR_TDENUMERATION_HXX */
+