xref: /aoo41x/main/stoc/source/tdmanager/tdmgr.cxx (revision 647a425c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_stoc.hxx"
26 #include <osl/diagnose.h>
27 #include <osl/mutex.hxx>
28 #include "rtl/ustrbuf.hxx"
29 #include <cppuhelper/factory.hxx>
30 #ifndef _CPPUHELPER_IMPLBASE5_HXX_
31 #include <cppuhelper/compbase5.hxx>
32 #endif
33 #include <cppuhelper/implbase1.hxx>
34 #ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
35 #include <cppuhelper/implementationentry.hxx>
36 #endif
37 #include "tdmgr_common.hxx"
38 #include "tdmgr_tdenumeration.hxx"
39 #include "lrucache.hxx"
40 
41 #include <com/sun/star/lang/XServiceInfo.hpp>
42 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
43 #include <com/sun/star/lang/XEventListener.hpp>
44 #include <com/sun/star/lang/XTypeProvider.hpp>
45 #include <com/sun/star/lang/XComponent.hpp>
46 #include <com/sun/star/lang/XInitialization.hpp>
47 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
48 #include <com/sun/star/container/XSet.hpp>
49 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
50 #include <com/sun/star/reflection/XTypeDescription.hpp>
51 #include <com/sun/star/reflection/XArrayTypeDescription.hpp>
52 #include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
53 #include <com/sun/star/reflection/XInterfaceTypeDescription.hpp>
54 #include "com/sun/star/reflection/XStructTypeDescription.hpp"
55 #include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
56 #include <com/sun/star/registry/XRegistryKey.hpp>
57 #include "com/sun/star/uno/RuntimeException.hpp"
58 
59 #include <algorithm>
60 #include <vector>
61 
62 using namespace std;
63 using namespace cppu;
64 using namespace rtl;
65 using namespace osl;
66 using namespace com::sun::star;
67 using namespace com::sun::star::uno;
68 using namespace com::sun::star::lang;
69 using namespace com::sun::star::reflection;
70 using namespace com::sun::star::container;
71 using namespace com::sun::star::registry;
72 
73 
74 
75 static const sal_Int32 CACHE_SIZE = 512;
76 
77 #define SERVICENAME "com.sun.star.reflection.TypeDescriptionManager"
78 #define IMPLNAME	"com.sun.star.comp.stoc.TypeDescriptionManager"
79 
80 //--------------------------------------------------------------------------------------------------
81 // exported via tdmgr_common.hxx
82 extern rtl_StandardModuleCount g_moduleCount;
83 
84 namespace stoc_bootstrap
85 {
tdmgr_getSupportedServiceNames()86 Sequence< OUString > SAL_CALL tdmgr_getSupportedServiceNames()
87 {
88 	static Sequence < OUString > *pNames = 0;
89 	if( ! pNames )
90 	{
91 		MutexGuard guard( Mutex::getGlobalMutex() );
92 		if( !pNames )
93 		{
94 			static Sequence< OUString > seqNames(1);
95 			seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
96 			pNames = &seqNames;
97 		}
98 	}
99 	return *pNames;
100 }
101 
tdmgr_getImplementationName()102 OUString SAL_CALL tdmgr_getImplementationName()
103 {
104 	static OUString *pImplName = 0;
105 	if( ! pImplName )
106 	{
107 		MutexGuard guard( Mutex::getGlobalMutex() );
108 		if( ! pImplName )
109 		{
110 			static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
111 			pImplName = &implName;
112 		}
113 	}
114 	return *pImplName;
115 }
116 }
117 
118 namespace stoc_tdmgr
119 {
120 typedef vector< Reference< XHierarchicalNameAccess > > ProviderVector;
121 
122 class EnumerationImpl;
123 class ManagerImpl;
124 
125 //==================================================================================================
126 class EventListenerImpl : public ImplHelper1< XEventListener >
127 {
128 	ManagerImpl *		_pMgr;
129 
130 public:
EventListenerImpl(ManagerImpl * pMgr)131 	EventListenerImpl( ManagerImpl * pMgr )
132 		: _pMgr( pMgr )
133 		{
134 			::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt );
135 		}
136 	virtual ~EventListenerImpl();
137 
138 	// lifetime delegated to manager
139 	virtual void SAL_CALL acquire() throw();
140 	virtual void SAL_CALL release() throw();
141 
142 	// XEventListener
143 	virtual void SAL_CALL disposing( const EventObject & rEvt ) throw(::com::sun::star::uno::RuntimeException);
144 };
145 
~EventListenerImpl()146 EventListenerImpl::~EventListenerImpl()
147 {
148 	::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt );
149 }
150 
151 //==================================================================================================
152 class ManagerImpl
153     : public WeakComponentImplHelper5< XServiceInfo,
154                                        XSet,
155                                        XHierarchicalNameAccess,
156                                        XTypeDescriptionEnumerationAccess,
157                                        XInitialization >
158 {
159 	friend class EnumerationImpl;
160 	friend class EventListenerImpl;
161 
162 	Mutex								_aComponentMutex;
163 	Reference< XComponentContext >      _xContext;
164 	EventListenerImpl					_aEventListener;
165 
166 	// elements
167 	sal_Bool							_bCaching;
168 	LRU_CacheAnyByOUString				_aElements;
169 	// provider chain
170 	ProviderVector						_aProviders;
171 
172 	inline Any getSimpleType( const OUString & rName );
173 
174     Reference< XTypeDescription > getInstantiatedStruct(OUString const & name);
175 
176 protected:
177 	virtual void SAL_CALL disposing();
178 
179 public:
180 	ManagerImpl( Reference< XComponentContext > const & xContext, sal_Int32 nCacheSize );
181 	virtual ~ManagerImpl();
182 
183     // XInitialization
184     virtual void SAL_CALL initialize( const Sequence< Any > & args ) throw (Exception, RuntimeException);
185 
186 	// XServiceInfo
187 	virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
188 	virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException);
189 	virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
190 
191 	// XElementAccess
192     virtual Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException);
193     virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException);
194 
195 	// XEnumerationAccess
196     virtual Reference< XEnumeration > SAL_CALL createEnumeration() throw(::com::sun::star::uno::RuntimeException);
197 
198 	// XSet
199     virtual sal_Bool SAL_CALL has( const Any & rElement ) throw(::com::sun::star::uno::RuntimeException);
200     virtual void SAL_CALL insert( const Any & rElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
201     virtual void SAL_CALL remove( const Any & rElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
202 
203 	// XHierarchicalNameAccess
204 	virtual Any SAL_CALL getByHierarchicalName( const OUString & rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
205 	virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
206 
207     // XTypeDescriptionEnumerationAccess
208     virtual ::com::sun::star::uno::Reference<
209         ::com::sun::star::reflection::XTypeDescriptionEnumeration > SAL_CALL
210     createTypeDescriptionEnumeration(
211         const ::rtl::OUString& moduleName,
212         const ::com::sun::star::uno::Sequence<
213             ::com::sun::star::uno::TypeClass >& types,
214         ::com::sun::star::reflection::TypeDescriptionSearchDepth depth )
215             throw ( ::com::sun::star::reflection::NoSuchTypeNameException,
216                     ::com::sun::star::reflection::InvalidTypeNameException,
217                     ::com::sun::star::uno::RuntimeException );
218 };
219 
220 //==================================================================================================
221 class EnumerationImpl
222 	: public WeakImplHelper1< XEnumeration >
223 {
224 	ManagerImpl *		_pMgr;
225 	size_t				_nPos;
226 
227 public:
228 	EnumerationImpl( ManagerImpl * pManager );
229 	virtual ~EnumerationImpl();
230 
231 	// XEnumeration
232 	virtual sal_Bool SAL_CALL hasMoreElements() throw(::com::sun::star::uno::RuntimeException);
233 	virtual Any SAL_CALL nextElement() throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
234 };
235 
236 //##################################################################################################
237 
238 // lifetime delegated to manager
239 //__________________________________________________________________________________________________
acquire()240 void EventListenerImpl::acquire() throw()
241 {
242 	_pMgr->acquire();
243 }
244 //__________________________________________________________________________________________________
release()245 void EventListenerImpl::release() throw()
246 {
247 	_pMgr->release();
248 }
249 
250 // XEventListener
251 //__________________________________________________________________________________________________
disposing(const EventObject & rEvt)252 void EventListenerImpl::disposing( const EventObject & rEvt )
253 	throw(::com::sun::star::uno::RuntimeException)
254 {
255     _pMgr->remove( makeAny( rEvt.Source ) );
256 }
257 
258 //##################################################################################################
259 
260 //__________________________________________________________________________________________________
EnumerationImpl(ManagerImpl * pManager)261 EnumerationImpl::EnumerationImpl( ManagerImpl * pManager )
262 	: _pMgr( pManager )
263 	, _nPos( 0 )
264 {
265 	_pMgr->acquire();
266 }
267 //__________________________________________________________________________________________________
~EnumerationImpl()268 EnumerationImpl::~EnumerationImpl()
269 {
270 	_pMgr->release();
271 }
272 
273 // XEnumeration
274 //__________________________________________________________________________________________________
hasMoreElements()275 sal_Bool EnumerationImpl::hasMoreElements()
276 	throw(::com::sun::star::uno::RuntimeException)
277 {
278 	MutexGuard aGuard( _pMgr->_aComponentMutex );
279 	return (_nPos < _pMgr->_aProviders.size());
280 }
281 //__________________________________________________________________________________________________
nextElement()282 Any EnumerationImpl::nextElement()
283 	throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
284 {
285 	MutexGuard aGuard( _pMgr->_aComponentMutex );
286 	if (_nPos >= _pMgr->_aProviders.size())
287 	{
288 		throw NoSuchElementException(
289 			OUString( RTL_CONSTASCII_USTRINGPARAM("there is no further element!") ),
290 			(XWeak *)(OWeakObject *)this );
291 	}
292 	return makeAny( _pMgr->_aProviders[_nPos++] );
293 }
294 
295 //##################################################################################################
296 
297 //__________________________________________________________________________________________________
ManagerImpl(Reference<XComponentContext> const & xContext,sal_Int32 nCacheSize)298 ManagerImpl::ManagerImpl(
299     Reference< XComponentContext > const & xContext, sal_Int32 nCacheSize )
300     : WeakComponentImplHelper5<
301         XServiceInfo, XSet, XHierarchicalNameAccess,
302         XTypeDescriptionEnumerationAccess, XInitialization >( _aComponentMutex )
303     , _xContext( xContext )
304 	, _aEventListener( this )
305 	, _bCaching( sal_True )
306 	, _aElements( nCacheSize )
307 {
308 	::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt );
309 }
310 //__________________________________________________________________________________________________
~ManagerImpl()311 ManagerImpl::~ManagerImpl()
312 {
313 	OSL_ENSURE( _aProviders.size() == 0, "### still providers left!" );
314 	OSL_TRACE( "> TypeDescriptionManager shut down. <\n" );
315 	::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt );
316 }
317 //__________________________________________________________________________________________________
disposing()318 void ManagerImpl::disposing()
319 {
320     // called on disposing the tdmgr instance (supposedly from context)
321     _bCaching = sal_False;
322     _aElements.clear();
323     _xContext.clear();
324 	_aProviders.clear();
325 }
326 
327 // XInitialization
328 //__________________________________________________________________________________________________
initialize(const Sequence<Any> & args)329 void ManagerImpl::initialize(
330     const Sequence< Any > & args )
331     throw (Exception, RuntimeException)
332 {
333 	// additional providers
334     Any const * pProviders = args.getConstArray();
335     for ( sal_Int32 nPos = 0; nPos < args.getLength(); ++nPos )
336     {
337         Reference< XHierarchicalNameAccess > xHA( pProviders[ nPos ], UNO_QUERY );
338         OSL_ENSURE( xHA.is(), "### no td provider!" );
339 
340         if (xHA.is())
341         {
342             try
343             {
344                 insert( makeAny( xHA ) );
345             }
346             catch (IllegalArgumentException &)
347             {
348             }
349             catch (ElementExistException &)
350             {
351             }
352         }
353     }
354 }
355 
356 // XServiceInfo
357 //__________________________________________________________________________________________________
getImplementationName()358 OUString ManagerImpl::getImplementationName()
359 	throw(::com::sun::star::uno::RuntimeException)
360 {
361 	return stoc_bootstrap::tdmgr_getImplementationName();
362 }
363 //__________________________________________________________________________________________________
supportsService(const OUString & rServiceName)364 sal_Bool ManagerImpl::supportsService( const OUString & rServiceName )
365 	throw(::com::sun::star::uno::RuntimeException)
366 {
367 	const Sequence< OUString > & rSNL = getSupportedServiceNames();
368 	const OUString * pArray = rSNL.getConstArray();
369 	for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
370 	{
371 		if (pArray[nPos] == rServiceName)
372 			return sal_True;
373 	}
374 	return sal_False;
375 }
376 //__________________________________________________________________________________________________
getSupportedServiceNames()377 Sequence< OUString > ManagerImpl::getSupportedServiceNames()
378 	throw(::com::sun::star::uno::RuntimeException)
379 {
380 	return stoc_bootstrap::tdmgr_getSupportedServiceNames();
381 }
382 
383 // XElementAccess
384 //__________________________________________________________________________________________________
getElementType()385 Type ManagerImpl::getElementType()
386 	throw(::com::sun::star::uno::RuntimeException)
387 {
388 	return ::getCppuType( (const Reference< XHierarchicalNameAccess > *)0 );
389 }
390 //__________________________________________________________________________________________________
hasElements()391 sal_Bool ManagerImpl::hasElements()
392 	throw(::com::sun::star::uno::RuntimeException)
393 {
394 	MutexGuard aGuard( _aComponentMutex );
395 	return (_aProviders.size() > 0);
396 }
397 
398 // XEnumerationAccess
399 //__________________________________________________________________________________________________
createEnumeration()400 Reference< XEnumeration > ManagerImpl::createEnumeration()
401 	throw(::com::sun::star::uno::RuntimeException)
402 {
403 	return new EnumerationImpl( this );
404 }
405 
406 // XSet
407 //__________________________________________________________________________________________________
has(const Any & rElement)408 sal_Bool SAL_CALL ManagerImpl::has( const Any & rElement )
409 	throw(::com::sun::star::uno::RuntimeException)
410 {
411 	Reference< XHierarchicalNameAccess > xElem;
412 	if (rElement >>= xElem)
413 	{
414 		MutexGuard aGuard( _aComponentMutex );
415 		return (find( _aProviders.begin(), _aProviders.end(), xElem ) != _aProviders.end());
416 	}
417 	return sal_False;
418 }
419 
420 //__________________________________________________________________________________________________
insert(const Any & rElement)421 void SAL_CALL ManagerImpl::insert( const Any & rElement )
422 	throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException)
423 {
424 	Reference< XHierarchicalNameAccess > xElem;
425 	if (! (rElement >>= xElem) || !xElem.is())
426 	{
427 		throw IllegalArgumentException(
428 			OUString( RTL_CONSTASCII_USTRINGPARAM("no valid type description provider given!") ),
429 			(XWeak *)(OWeakObject *)this, 0 );
430 	}
431 
432 	MutexGuard aGuard( _aComponentMutex );
433 	if (find( _aProviders.begin(), _aProviders.end(), xElem ) != _aProviders.end())
434 	{
435 		throw ElementExistException(
436 			OUString( RTL_CONSTASCII_USTRINGPARAM("provider already inserted!") ),
437 			(XWeak *)(OWeakObject *)this );
438 	}
439 
440     if (! _aProviders.empty())
441     {
442         // check whether all types are compatible, if possible:
443         Reference<reflection::XTypeDescriptionEnumerationAccess> xTDEnumAccess(
444             xElem, UNO_QUERY );
445         OSL_ENSURE( xTDEnumAccess.is(),
446                     "### providers ought to implement "
447                     "reflection::XTypeDescriptionEnumerationAccess!" );
448         if (xTDEnumAccess.is())
449         {
450             try
451             {
452                 TypeClass ar [] = {
453                     TypeClass_ENUM, TypeClass_TYPEDEF, TypeClass_SEQUENCE,
454                     TypeClass_STRUCT, TypeClass_EXCEPTION,
455                     /* TypeClass_UNION, TypeClass_ARRAY not supported */
456                     TypeClass_INTERFACE,
457                     TypeClass_SERVICE,
458                     TypeClass_INTERFACE_METHOD, TypeClass_INTERFACE_ATTRIBUTE,
459                     TypeClass_PROPERTY, TypeClass_CONSTANT, TypeClass_CONSTANTS,
460                     TypeClass_SINGLETON
461                 };
462                 Reference<reflection::XTypeDescriptionEnumeration> xTDEnum(
463                     xTDEnumAccess->createTypeDescriptionEnumeration(
464                         OUString() /* all modules */,
465                         Sequence<TypeClass>( ar, ARLEN(ar) ),
466                         reflection::TypeDescriptionSearchDepth_INFINITE ) );
467 
468                 while (xTDEnum->hasMoreElements())
469                 {
470                     Reference<reflection::XTypeDescription> xNewTD;
471                     try
472                     {
473                         xNewTD = xTDEnum->nextTypeDescription();
474                     }
475                     catch (container::NoSuchElementException & exc)
476                     {
477                         throw lang::IllegalArgumentException(
478                             OUSTR("NoSuchElementException occured: ") +
479                             exc.Message, static_cast<OWeakObject *>(this),
480                             -1 /* unknown */ );
481                     }
482 
483                     try
484                     {
485                         OUString newName( xNewTD->getName() );
486                         Reference<reflection::XTypeDescription> xExistingTD(
487                             getByHierarchicalName( newName ), UNO_QUERY );
488                         OSL_ASSERT( xExistingTD.is() );
489                         // existing, check whether compatible:
490                         if (xExistingTD.is())
491                         {
492                             try
493                             {
494                                 check( xNewTD, xExistingTD );
495                             }
496                             catch (IncompatibleTypeException & exc)
497                             {
498                                 throw lang::IllegalArgumentException(
499                                     OUSTR("Rejecting types due to "
500                                           "incompatibility!  ") + exc.m_cause,
501                                     static_cast<OWeakObject *>(this), 0 );
502                             }
503                         }
504                     }
505                     catch (container::NoSuchElementException &)
506                     {
507                         // type not in: ok
508                     }
509                 }
510             }
511             catch (reflection::NoSuchTypeNameException & exc)
512             {
513                 throw lang::IllegalArgumentException(
514                     OUSTR("NoSuchTypeNameException occured: ") + exc.Message,
515                     static_cast<OWeakObject *>(this), -1 /* unknown */ );
516             }
517             catch (reflection::InvalidTypeNameException & exc)
518             {
519                 throw lang::IllegalArgumentException(
520                     OUSTR("InvalidTypeNameException occured: ") + exc.Message,
521                     static_cast<OWeakObject *>(this), -1 /* unknown */ );
522             }
523         }
524     }
525 
526 	_aProviders.push_back( xElem );
527 	Reference< XComponent > xComp( xElem, UNO_QUERY );
528 	if (xComp.is())
529 		xComp->addEventListener( &_aEventListener );
530 }
531 //__________________________________________________________________________________________________
remove(const Any & rElement)532 void SAL_CALL ManagerImpl::remove( const Any & rElement )
533 	throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
534 {
535 	if (!rBHelper.bDisposed && !rBHelper.bInDispose)
536 	{
537 		Reference< XHierarchicalNameAccess > xElem;
538 		if (! (rElement >>= xElem))
539 		{
540 			throw IllegalArgumentException(
541 				OUString( RTL_CONSTASCII_USTRINGPARAM("no type description provider given!") ),
542 				(XWeak *)(OWeakObject *)this, 0 );
543 		}
544 
545 		MutexGuard aGuard( _aComponentMutex );
546 		ProviderVector::iterator iFind( find( _aProviders.begin(), _aProviders.end(), xElem ) );
547 		if (iFind == _aProviders.end())
548 		{
549 			throw NoSuchElementException(
550 				OUString( RTL_CONSTASCII_USTRINGPARAM("provider not found!") ),
551 				(XWeak *)(OWeakObject *)this );
552 		}
553 		_aProviders.erase( iFind );
554 	}
555 
556 	Reference< XComponent > xComp;
557 	if (rElement >>= xComp)
558 		xComp->removeEventListener( &_aEventListener );
559 }
560 
561 // XTypeDescriptionEnumerationAccess
562 //__________________________________________________________________________________________________
563 // virtual
564 Reference< XTypeDescriptionEnumeration > SAL_CALL
createTypeDescriptionEnumeration(const OUString & moduleName,const Sequence<TypeClass> & types,TypeDescriptionSearchDepth depth)565 ManagerImpl::createTypeDescriptionEnumeration(
566         const OUString & moduleName,
567         const Sequence< TypeClass > & types,
568         TypeDescriptionSearchDepth depth )
569     throw ( NoSuchTypeNameException,
570             InvalidTypeNameException,
571             RuntimeException )
572 {
573     MutexGuard aGuard( _aComponentMutex );
574 
575     TDEnumerationAccessStack aStack;
576     ProviderVector::const_iterator it = _aProviders.begin();
577     const ProviderVector::const_iterator end = _aProviders.end();
578     while ( it != end )
579     {
580         Reference< XTypeDescriptionEnumerationAccess >xEnumAccess(
581             (*it), UNO_QUERY );
582         OSL_ENSURE( xEnumAccess.is(),
583                     "### no XTypeDescriptionEnumerationAccess!" );
584         if ( xEnumAccess.is() )
585             aStack.push( xEnumAccess );
586 
587         it++;
588     }
589 
590     return Reference< XTypeDescriptionEnumeration >(
591         new TypeDescriptionEnumerationImpl( moduleName,
592                                             types,
593                                             depth,
594                                             aStack ) );
595 }
596 
597 
598 //##################################################################################################
599 //##################################################################################################
600 //##################################################################################################
601 
602 
603 //==================================================================================================
604 class SimpleTypeDescriptionImpl
605     : public WeakImplHelper1< XTypeDescription >
606 {
607 	TypeClass _eTC;
608 	OUString  _aName;
609 
610 public:
SimpleTypeDescriptionImpl(TypeClass eTC,const OUString & rName)611 	SimpleTypeDescriptionImpl( TypeClass eTC, const OUString & rName )
612 		: _eTC( eTC )
613 		, _aName( rName )
614 		{}
615 
616 	// XTypeDescription
617 	virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
618 	virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
619 };
620 
621 // XTypeDescription
622 //__________________________________________________________________________________________________
getTypeClass()623 TypeClass SimpleTypeDescriptionImpl::getTypeClass()
624 	throw(::com::sun::star::uno::RuntimeException)
625 {
626 	return _eTC;
627 }
628 //__________________________________________________________________________________________________
getName()629 OUString SimpleTypeDescriptionImpl::getName()
630 	throw(::com::sun::star::uno::RuntimeException)
631 {
632 	return _aName;
633 }
634 
635 //==================================================================================================
636 class SequenceTypeDescriptionImpl
637     : public WeakImplHelper1< XIndirectTypeDescription >
638 {
639 	Reference< XTypeDescription > _xElementTD;
640 
641 public:
SequenceTypeDescriptionImpl(const Reference<XTypeDescription> & xElementTD)642 	SequenceTypeDescriptionImpl( const Reference< XTypeDescription > & xElementTD )
643 		: _xElementTD( xElementTD )
644 		{}
645 
646 	// XTypeDescription
647 	virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
648 	virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
649 
650 	// XIndirectTypeDescription
651     virtual Reference< XTypeDescription > SAL_CALL getReferencedType() throw(::com::sun::star::uno::RuntimeException);
652 };
653 
654 // XTypeDescription
655 //__________________________________________________________________________________________________
getTypeClass()656 TypeClass SequenceTypeDescriptionImpl::getTypeClass()
657 	throw(::com::sun::star::uno::RuntimeException)
658 {
659 	return TypeClass_SEQUENCE;
660 }
661 //__________________________________________________________________________________________________
getName()662 OUString SequenceTypeDescriptionImpl::getName()
663 	throw(::com::sun::star::uno::RuntimeException)
664 {
665 	return (OUString( RTL_CONSTASCII_USTRINGPARAM("[]") ) + _xElementTD->getName());
666 }
667 
668 // XIndirectTypeDescription
669 //__________________________________________________________________________________________________
getReferencedType()670 Reference< XTypeDescription > SequenceTypeDescriptionImpl::getReferencedType()
671 	throw(::com::sun::star::uno::RuntimeException)
672 {
673 	return _xElementTD;
674 }
675 
676 //==================================================================================================
677 class ArrayTypeDescriptionImpl
678     : public WeakImplHelper1< XArrayTypeDescription >
679 {
680 	Reference< XTypeDescription > _xElementTD;
681 	Mutex	 					  _aDimensionMutex;
682 	sal_Int32					  _nDimensions;
683 	Sequence< sal_Int32 >		  _seqDimensions;
684 	OUString					  _sDimensions;
685 
686 	void initDimensions(const OUString& rSDimensions);
687 public:
ArrayTypeDescriptionImpl(const Reference<XTypeDescription> & xElementTD,sal_Int32 nDimensions,const OUString & rSDimensions)688 	ArrayTypeDescriptionImpl( const Reference< XTypeDescription > & xElementTD,
689 							  sal_Int32 nDimensions, const OUString& rSDimensions )
690 		: _xElementTD( xElementTD )
691 		, _nDimensions( nDimensions )
692 		, _seqDimensions( Sequence< sal_Int32 >(nDimensions) )
693 		, _sDimensions( rSDimensions )
694 		{
695 			initDimensions( rSDimensions );
696 		}
~ArrayTypeDescriptionImpl()697 	virtual ~ArrayTypeDescriptionImpl() {}
698 
699 	// XTypeDescription
700 	virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
701 	virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
702 
703 	// XArrayTypeDescription
704     virtual Reference< XTypeDescription > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
705     virtual sal_Int32 SAL_CALL getNumberOfDimensions() throw(::com::sun::star::uno::RuntimeException);
706     virtual Sequence< sal_Int32 > SAL_CALL getDimensions() throw(::com::sun::star::uno::RuntimeException);
707 };
708 //__________________________________________________________________________________________________
unicodeToInteger(sal_Int8 base,const sal_Unicode * s)709 static sal_Int32 unicodeToInteger( sal_Int8 base, const sal_Unicode *s )
710 {
711 	sal_Int32    r = 0;
712 	sal_Int32    negative = 0;
713 
714 	if (*s == '-')
715    	{
716     	negative = 1;
717       	s++;
718    	}
719    	if (base == 8 && *s == '0')
720 		s++;
721    	else if (base == 16 && *s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
722     	s += 2;
723 
724    	for (; *s; s++)
725    	{
726    		if (*s <= '9' && *s >= '0')
727         	r = (r * base) + (*s - '0');
728       	else if (base > 10 && *s <= 'f' && *s >= 'a')
729         	r = (r * base) + (*s - 'a' + 10);
730       	else if (base > 10 && *s <= 'F' && *s >= 'A')
731         	r = (r * base) + (*s - 'A' + 10);
732        	else
733         	break;
734 	}
735    	if (negative) r *= -1;
736 	return r;
737 }
738 //__________________________________________________________________________________________________
initDimensions(const OUString & rSDimensions)739 void ArrayTypeDescriptionImpl::initDimensions(const OUString& rSDimensions)
740 {
741 	MutexGuard aGuard( _aDimensionMutex );
742 
743 	sal_Int32 *	 pDimensions = _seqDimensions.getArray();
744 	OUString tmp(rSDimensions);
745 	sal_Unicode* p = (sal_Unicode*)tmp.getStr()+1;
746 	sal_Unicode* pOffset = p;
747 	sal_Int32 len = tmp.getLength() - 1 ;
748 	sal_Int32 i = 0;
749 
750 	while ( len > 0)
751 	{
752 		pOffset++;
753 		if (*pOffset == ']')
754 		{
755 			*pOffset = '\0';
756 			pOffset += 2;
757 			len -= 3;
758 			pDimensions[i++] = unicodeToInteger(10, p);
759 			p = pOffset;
760 		} else
761 			len--;
762 	}
763 }
764 
765 // XTypeDescription
766 //__________________________________________________________________________________________________
getTypeClass()767 TypeClass ArrayTypeDescriptionImpl::getTypeClass()
768 	throw(::com::sun::star::uno::RuntimeException)
769 {
770 	return TypeClass_ARRAY;
771 }
772 //__________________________________________________________________________________________________
getName()773 OUString ArrayTypeDescriptionImpl::getName()
774 	throw(::com::sun::star::uno::RuntimeException)
775 {
776 	return (_xElementTD->getName() + _sDimensions);
777 }
778 
779 // XArrayTypeDescription
780 //__________________________________________________________________________________________________
getType()781 Reference< XTypeDescription > ArrayTypeDescriptionImpl::getType()
782 	throw(::com::sun::star::uno::RuntimeException)
783 {
784 	return _xElementTD;
785 }
786 
787 //__________________________________________________________________________________________________
getNumberOfDimensions()788 sal_Int32 ArrayTypeDescriptionImpl::getNumberOfDimensions()
789 	throw(::com::sun::star::uno::RuntimeException)
790 {
791 	return _nDimensions;
792 }
793 
794 //__________________________________________________________________________________________________
getDimensions()795 Sequence< sal_Int32 > ArrayTypeDescriptionImpl::getDimensions()
796 	throw(::com::sun::star::uno::RuntimeException)
797 {
798 	return _seqDimensions;
799 }
800 
801 //##################################################################################################
802 //##################################################################################################
803 //##################################################################################################
804 
805 
806 //__________________________________________________________________________________________________
getSimpleType(const OUString & rName)807 inline Any ManagerImpl::getSimpleType( const OUString & rName )
808 {
809 	Any aRet;
810 
811 	if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("string") ))
812 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_STRING, rName ) );
813 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("long") ))
814 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_LONG, rName ) );
815 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned long") ))
816 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_LONG, rName ) );
817 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("boolean") ))
818 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_BOOLEAN, rName ) );
819 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("char") ))
820 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_CHAR, rName ) );
821 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("byte") ))
822 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_BYTE, rName ) );
823 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("short") ))
824 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_SHORT, rName ) );
825 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned short") ))
826 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_SHORT, rName ) );
827 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("hyper") ))
828 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_HYPER, rName ) );
829 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned hyper") ))
830 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_HYPER, rName ) );
831 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("float") ))
832 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_FLOAT, rName ) );
833 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("double") ))
834 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_DOUBLE, rName ) );
835 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("any") ))
836 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_ANY, rName ) );
837 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("void") ))
838 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_VOID, rName ) );
839 	else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("type") ))
840 		aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_TYPE, rName ) );
841 
842 	return aRet;
843 }
844 
845 namespace {
846 
resolveTypedefs(Reference<XTypeDescription> const & type)847 Reference< XTypeDescription > resolveTypedefs(
848     Reference< XTypeDescription > const & type)
849 {
850     Reference< XTypeDescription > resolved(type);
851     while (resolved->getTypeClass() == TypeClass_TYPEDEF) {
852         resolved = Reference< XIndirectTypeDescription >(
853             type, UNO_QUERY_THROW)->getReferencedType();
854     }
855     return resolved;
856 }
857 
isNonVoidNonExceptionType(Reference<XTypeDescription> const & type)858 bool isNonVoidNonExceptionType(Reference< XTypeDescription > const & type) {
859     switch (type->getTypeClass()) {
860     case TypeClass_BOOLEAN:
861     case TypeClass_BYTE:
862     case TypeClass_SHORT:
863     case TypeClass_UNSIGNED_SHORT:
864     case TypeClass_LONG:
865     case TypeClass_UNSIGNED_LONG:
866     case TypeClass_HYPER:
867     case TypeClass_UNSIGNED_HYPER:
868     case TypeClass_FLOAT:
869     case TypeClass_DOUBLE:
870     case TypeClass_CHAR:
871     case TypeClass_STRING:
872     case TypeClass_TYPE:
873     case TypeClass_ANY:
874     case TypeClass_SEQUENCE:
875     case TypeClass_ENUM:
876     case TypeClass_STRUCT:
877     case TypeClass_INTERFACE:
878         return true;
879 
880     default:
881         return false;
882     }
883 }
884 
885 class InstantiatedStruct: public WeakImplHelper1< XStructTypeDescription > {
886 public:
887     InstantiatedStruct(
888         Reference< XStructTypeDescription > const & structType,
889         std::vector< Reference< XTypeDescription > > const & arguments);
890 
getTypeClass()891     virtual TypeClass SAL_CALL getTypeClass() throw (RuntimeException)
892     { return TypeClass_STRUCT; }
893 
894     virtual OUString SAL_CALL getName() throw (RuntimeException);
895 
getBaseType()896     virtual Reference< XTypeDescription > SAL_CALL getBaseType()
897         throw (RuntimeException)
898     { return m_struct->getBaseType(); }
899 
900     virtual Sequence< Reference< XTypeDescription > > SAL_CALL getMemberTypes()
901         throw (RuntimeException);
902 
getMemberNames()903     virtual Sequence< OUString > SAL_CALL getMemberNames()
904         throw (RuntimeException)
905     { return m_struct->getMemberNames(); }
906 
getTypeParameters()907     virtual Sequence< OUString > SAL_CALL getTypeParameters()
908         throw (RuntimeException)
909     { return Sequence< OUString >(); }
910 
911     virtual Sequence< Reference< XTypeDescription > > SAL_CALL
getTypeArguments()912     getTypeArguments() throw (RuntimeException)
913     { return m_arguments; }
914 
915 private:
916     Reference< XStructTypeDescription > m_struct;
917     Sequence< Reference< XTypeDescription > > m_arguments;
918 };
919 
InstantiatedStruct(Reference<XStructTypeDescription> const & structType,std::vector<Reference<XTypeDescription>> const & arguments)920 InstantiatedStruct::InstantiatedStruct(
921     Reference< XStructTypeDescription > const & structType,
922     std::vector< Reference< XTypeDescription > > const & arguments):
923     m_struct(structType),
924     m_arguments(static_cast< sal_Int32 >(arguments.size()))
925 {
926     for (std::vector< Reference< XTypeDescription > >::size_type i = 0;
927          i < arguments.size(); ++i)
928     {
929         m_arguments[static_cast< sal_Int32 >(i)] = arguments[i];
930     }
931 }
932 
getName()933 OUString InstantiatedStruct::getName() throw (RuntimeException) {
934     OUStringBuffer buf(m_struct->getName());
935     buf.append(static_cast< sal_Unicode >('<'));
936     for (sal_Int32 i = 0; i < m_arguments.getLength(); ++i) {
937         if (i != 0) {
938             buf.append(static_cast< sal_Unicode >(','));
939         }
940         buf.append(m_arguments[i]->getName());
941     }
942     buf.append(static_cast< sal_Unicode >('>'));
943     return buf.makeStringAndClear();
944 }
945 
getMemberTypes()946 Sequence< Reference< XTypeDescription > > InstantiatedStruct::getMemberTypes()
947     throw (RuntimeException)
948 {
949     Sequence< Reference< XTypeDescription > > types(m_struct->getMemberTypes());
950     for (sal_Int32 i = 0; i < types.getLength(); ++i) {
951         if (types[i]->getTypeClass() == TypeClass_UNKNOWN) {
952             Sequence< OUString > parameters(m_struct->getTypeParameters());
953             OSL_ASSERT(parameters.getLength() == m_arguments.getLength());
954             for (sal_Int32 j = 0; j < parameters.getLength(); ++j) {
955                 if (parameters[j] == types[i]->getName()) {
956                     types[i] = m_arguments[j];
957                     break;
958                 }
959             }
960         }
961     }
962     return types;
963 }
964 
965 }
966 
getInstantiatedStruct(OUString const & name)967 Reference< XTypeDescription > ManagerImpl::getInstantiatedStruct(
968     OUString const & name)
969 {
970     sal_Int32 i = name.indexOf('<');
971     OSL_ASSERT(i >= 0);
972     Reference< XStructTypeDescription > structType(
973         getByHierarchicalName(name.copy(0, i)), UNO_QUERY);
974     std::vector< Reference< XTypeDescription > > args;
975     bool good = structType.is();
976     if (good) {
977         do {
978             ++i; // skip '<' or ','
979             sal_Int32 j = i;
980             for (sal_Int32 level = 0; j != name.getLength(); ++j) {
981                 sal_Unicode c = name[j];
982                 if (c == ',') {
983                     if (level == 0) {
984                         break;
985                     }
986                 } else if (c == '<') {
987                     ++level;
988                 } else if (c == '>') {
989                     if (level == 0) {
990                         break;
991                     }
992                     --level;
993                 }
994             }
995             if (j != name.getLength()) {
996                 Reference< XTypeDescription > type(
997                     getByHierarchicalName(name.copy(i, j - i)), UNO_QUERY);
998                 if (isNonVoidNonExceptionType(resolveTypedefs(type))) {
999                     args.push_back(type);
1000                 } else {
1001                     good = false;
1002                     break;
1003                 }
1004             }
1005             i = j;
1006         } while (i != name.getLength() && name[i] != '>');
1007         good = good && i == name.getLength() - 1
1008             && name[i] == '>' && !args.empty();
1009     }
1010     // args.size() cannot exceed SAL_MAX_INT32, as each argument consumes at
1011     // least one position within an rtl::OUString (which is no longer than
1012     // SAL_MAX_INT32):
1013     if (!good
1014         || (args.size()
1015             != sal::static_int_cast< sal_uInt32 >(
1016                 structType->getTypeParameters().getLength())))
1017     {
1018         throw NoSuchElementException(name, static_cast< OWeakObject * >(this));
1019     }
1020     return new InstantiatedStruct(structType, args);
1021 }
1022 
1023 // XHierarchicalNameAccess
1024 //__________________________________________________________________________________________________
getByHierarchicalName(const OUString & rName)1025 Any ManagerImpl::getByHierarchicalName( const OUString & rName )
1026 	throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
1027 {
1028 	Any aRet;
1029 	if (_bCaching)
1030 		aRet = _aElements.getValue( rName );
1031 	if (rName.getLength() && !aRet.hasValue())
1032 	{
1033 		sal_Int32 nIndex;
1034 		if (rName[0] == '[') // test for sequence
1035 		{
1036 			Reference< XTypeDescription > xElemType(
1037                 getByHierarchicalName( rName.copy( 2 ) ),
1038                 UNO_QUERY_THROW );
1039             aRet <<= Reference< XTypeDescription >(
1040                 new SequenceTypeDescriptionImpl( xElemType ) );
1041 		}
1042 		else if (rName[rName.getLength()-1] == ']') // test for array
1043 		{
1044             sal_Int32 nIndex2 = 0, nTokens = 0;
1045             do { rName.getToken( 0, '[', nIndex2 ); nTokens++; } while( nIndex2 != -1 );
1046 			sal_Int32 nDims = nTokens - 1;
1047 			sal_Int32 dimOffset = rName.indexOf('[');
1048 			Reference< XTypeDescription > xElemType(
1049                 getByHierarchicalName( rName.copy( 0, dimOffset ) ),
1050                 UNO_QUERY_THROW );
1051             aRet <<= Reference< XTypeDescription >(
1052                 new ArrayTypeDescriptionImpl(
1053                     xElemType, nDims, rName.copy(dimOffset) ) );
1054 		}
1055         // test for interface member names:
1056 		else if ((nIndex = rName.indexOf( ':' )) >= 0)
1057 		{
1058 			Reference< XInterfaceTypeDescription > xIfaceTD(
1059                 getByHierarchicalName( rName.copy( 0, nIndex ) ),
1060                 UNO_QUERY_THROW );
1061             const Sequence< Reference< XInterfaceMemberTypeDescription > > &
1062                 rMembers = xIfaceTD->getMembers();
1063             const Reference< XInterfaceMemberTypeDescription > * pMembers =
1064                 rMembers.getConstArray();
1065 
1066             for ( sal_Int32 nPos = rMembers.getLength(); nPos--; )
1067             {
1068                 if (rName == pMembers[nPos]->getName())
1069                 {
1070                     aRet <<= Reference< XTypeDescription >(
1071                         pMembers[nPos], UNO_QUERY_THROW );
1072                     break;
1073                 }
1074             }
1075             if (! aRet.hasValue())
1076             {
1077                 // member not found:
1078                 throw NoSuchElementException(
1079                     rName, static_cast< OWeakObject * >(this) );
1080             }
1081 		}
1082         // test for instantiated polymorphic struct types:
1083         else if (rName.indexOf('<') >= 0)
1084         {
1085             aRet <<= getInstantiatedStruct(rName);
1086         }
1087 		else if (rName.indexOf( '.' ) < 0) // test for simple/ build in types
1088 		{
1089 			aRet = getSimpleType( rName );
1090 		}
1091 
1092 		if (! aRet.hasValue())
1093 		{
1094 			// last, try callback chain
1095 			for ( ProviderVector::const_iterator iPos( _aProviders.begin() );
1096 				  iPos != _aProviders.end(); ++iPos )
1097 			{
1098 				try
1099 				{
1100 					if ((aRet = (*iPos)->getByHierarchicalName(
1101                              rName )).hasValue())
1102                     {
1103 						break;
1104                     }
1105 				}
1106 				catch (NoSuchElementException &)
1107 				{
1108 				}
1109 			}
1110 		}
1111 
1112 		// update cache
1113 		if (_bCaching && aRet.hasValue())
1114 			_aElements.setValue( rName, aRet );
1115 	}
1116 
1117 	if (! aRet.hasValue())
1118 	{
1119 		throw NoSuchElementException(
1120             rName, static_cast< OWeakObject * >(this) );
1121 	}
1122 	return aRet;
1123 }
1124 //__________________________________________________________________________________________________
hasByHierarchicalName(const OUString & rName)1125 sal_Bool ManagerImpl::hasByHierarchicalName( const OUString & rName )
1126 	throw(::com::sun::star::uno::RuntimeException)
1127 {
1128 	try
1129 	{
1130 		return getByHierarchicalName( rName ).hasValue();
1131 	}
1132 	catch (NoSuchElementException &)
1133 	{
1134 	}
1135 	return sal_False;
1136 }
1137 }
1138 
1139 namespace stoc_bootstrap
1140 {
1141 //==================================================================================================
ManagerImpl_create(Reference<XComponentContext> const & xContext)1142 Reference< XInterface > SAL_CALL ManagerImpl_create(
1143     Reference< XComponentContext > const & xContext )
1144 	SAL_THROW( (::com::sun::star::uno::Exception) )
1145 {
1146     sal_Int32 nCacheSize = CACHE_SIZE;
1147     if (xContext.is()) {
1148         xContext->getValueByName(
1149             OUString(
1150                 RTL_CONSTASCII_USTRINGPARAM(
1151                     "/implementations/" IMPLNAME "/CacheSize"))) >>=
1152             nCacheSize;
1153     }
1154 
1155 	return Reference< XInterface >( *new stoc_tdmgr::ManagerImpl( xContext, nCacheSize ) );
1156 }
1157 
1158 }
1159 
1160