1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tdmgr.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_stoc.hxx"
33 #include <osl/diagnose.h>
34 #include <osl/mutex.hxx>
35 #include "rtl/ustrbuf.hxx"
36 #include <cppuhelper/factory.hxx>
37 #ifndef _CPPUHELPER_IMPLBASE5_HXX_
38 #include <cppuhelper/compbase5.hxx>
40 #include <cppuhelper/implbase1.hxx>
41 #ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
42 #include <cppuhelper/implementationentry.hxx>
44 #include "tdmgr_common.hxx"
45 #include "tdmgr_tdenumeration.hxx"
46 #include "lrucache.hxx"
48 #include <com/sun/star/lang/XServiceInfo.hpp>
49 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
50 #include <com/sun/star/lang/XEventListener.hpp>
51 #include <com/sun/star/lang/XTypeProvider.hpp>
52 #include <com/sun/star/lang/XComponent.hpp>
53 #include <com/sun/star/lang/XInitialization.hpp>
54 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
55 #include <com/sun/star/container/XSet.hpp>
56 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
57 #include <com/sun/star/reflection/XTypeDescription.hpp>
58 #include <com/sun/star/reflection/XArrayTypeDescription.hpp>
59 #include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
60 #include <com/sun/star/reflection/XInterfaceTypeDescription.hpp>
61 #include "com/sun/star/reflection/XStructTypeDescription.hpp"
62 #include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
63 #include <com/sun/star/registry/XRegistryKey.hpp>
64 #include "com/sun/star/uno/RuntimeException.hpp"
73 using namespace com::sun::star
;
74 using namespace com::sun::star::uno
;
75 using namespace com::sun::star::lang
;
76 using namespace com::sun::star::reflection
;
77 using namespace com::sun::star::container
;
78 using namespace com::sun::star::registry
;
82 static const sal_Int32 CACHE_SIZE
= 512;
84 #define SERVICENAME "com.sun.star.reflection.TypeDescriptionManager"
85 #define IMPLNAME "com.sun.star.comp.stoc.TypeDescriptionManager"
87 //--------------------------------------------------------------------------------------------------
88 // exported via tdmgr_common.hxx
89 extern rtl_StandardModuleCount g_moduleCount
;
91 namespace stoc_bootstrap
93 Sequence
< OUString
> SAL_CALL
tdmgr_getSupportedServiceNames()
95 static Sequence
< OUString
> *pNames
= 0;
98 MutexGuard
guard( Mutex::getGlobalMutex() );
101 static Sequence
< OUString
> seqNames(1);
102 seqNames
.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME
));
109 OUString SAL_CALL
tdmgr_getImplementationName()
111 static OUString
*pImplName
= 0;
114 MutexGuard
guard( Mutex::getGlobalMutex() );
117 static OUString
implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME
) );
118 pImplName
= &implName
;
127 typedef vector
< Reference
< XHierarchicalNameAccess
> > ProviderVector
;
129 class EnumerationImpl
;
132 //==================================================================================================
133 class EventListenerImpl
: public ImplHelper1
< XEventListener
>
138 EventListenerImpl( ManagerImpl
* pMgr
)
141 ::g_moduleCount
.modCnt
.acquire( &::g_moduleCount
.modCnt
);
143 virtual ~EventListenerImpl();
145 // lifetime delegated to manager
146 virtual void SAL_CALL
acquire() throw();
147 virtual void SAL_CALL
release() throw();
150 virtual void SAL_CALL
disposing( const EventObject
& rEvt
) throw(::com::sun::star::uno::RuntimeException
);
153 EventListenerImpl::~EventListenerImpl()
155 ::g_moduleCount
.modCnt
.release( &::g_moduleCount
.modCnt
);
158 //==================================================================================================
160 : public WeakComponentImplHelper5
< XServiceInfo
,
162 XHierarchicalNameAccess
,
163 XTypeDescriptionEnumerationAccess
,
166 friend class EnumerationImpl
;
167 friend class EventListenerImpl
;
169 Mutex _aComponentMutex
;
170 Reference
< XComponentContext
> _xContext
;
171 EventListenerImpl _aEventListener
;
175 LRU_CacheAnyByOUString _aElements
;
177 ProviderVector _aProviders
;
179 inline Any
getSimpleType( const OUString
& rName
);
181 Reference
< XTypeDescription
> getInstantiatedStruct(OUString
const & name
);
184 virtual void SAL_CALL
disposing();
187 ManagerImpl( Reference
< XComponentContext
> const & xContext
, sal_Int32 nCacheSize
);
188 virtual ~ManagerImpl();
191 virtual void SAL_CALL
initialize( const Sequence
< Any
> & args
) throw (Exception
, RuntimeException
);
194 virtual OUString SAL_CALL
getImplementationName() throw(::com::sun::star::uno::RuntimeException
);
195 virtual sal_Bool SAL_CALL
supportsService( const OUString
& rServiceName
) throw(::com::sun::star::uno::RuntimeException
);
196 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException
);
199 virtual Type SAL_CALL
getElementType() throw(::com::sun::star::uno::RuntimeException
);
200 virtual sal_Bool SAL_CALL
hasElements() throw(::com::sun::star::uno::RuntimeException
);
202 // XEnumerationAccess
203 virtual Reference
< XEnumeration
> SAL_CALL
createEnumeration() throw(::com::sun::star::uno::RuntimeException
);
206 virtual sal_Bool SAL_CALL
has( const Any
& rElement
) throw(::com::sun::star::uno::RuntimeException
);
207 virtual void SAL_CALL
insert( const Any
& rElement
) throw(::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::container::ElementExistException
, ::com::sun::star::uno::RuntimeException
);
208 virtual void SAL_CALL
remove( const Any
& rElement
) throw(::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::container::NoSuchElementException
, ::com::sun::star::uno::RuntimeException
);
210 // XHierarchicalNameAccess
211 virtual Any SAL_CALL
getByHierarchicalName( const OUString
& rName
) throw(::com::sun::star::container::NoSuchElementException
, ::com::sun::star::uno::RuntimeException
);
212 virtual sal_Bool SAL_CALL
hasByHierarchicalName( const OUString
& rName
) throw(::com::sun::star::uno::RuntimeException
);
214 // XTypeDescriptionEnumerationAccess
215 virtual ::com::sun::star::uno::Reference
<
216 ::com::sun::star::reflection::XTypeDescriptionEnumeration
> SAL_CALL
217 createTypeDescriptionEnumeration(
218 const ::rtl::OUString
& moduleName
,
219 const ::com::sun::star::uno::Sequence
<
220 ::com::sun::star::uno::TypeClass
>& types
,
221 ::com::sun::star::reflection::TypeDescriptionSearchDepth depth
)
222 throw ( ::com::sun::star::reflection::NoSuchTypeNameException
,
223 ::com::sun::star::reflection::InvalidTypeNameException
,
224 ::com::sun::star::uno::RuntimeException
);
227 //==================================================================================================
228 class EnumerationImpl
229 : public WeakImplHelper1
< XEnumeration
>
235 EnumerationImpl( ManagerImpl
* pManager
);
236 virtual ~EnumerationImpl();
239 virtual sal_Bool SAL_CALL
hasMoreElements() throw(::com::sun::star::uno::RuntimeException
);
240 virtual Any SAL_CALL
nextElement() throw(::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
);
243 //##################################################################################################
245 // lifetime delegated to manager
246 //__________________________________________________________________________________________________
247 void EventListenerImpl::acquire() throw()
251 //__________________________________________________________________________________________________
252 void EventListenerImpl::release() throw()
258 //__________________________________________________________________________________________________
259 void EventListenerImpl::disposing( const EventObject
& rEvt
)
260 throw(::com::sun::star::uno::RuntimeException
)
262 _pMgr
->remove( makeAny( rEvt
.Source
) );
265 //##################################################################################################
267 //__________________________________________________________________________________________________
268 EnumerationImpl::EnumerationImpl( ManagerImpl
* pManager
)
274 //__________________________________________________________________________________________________
275 EnumerationImpl::~EnumerationImpl()
281 //__________________________________________________________________________________________________
282 sal_Bool
EnumerationImpl::hasMoreElements()
283 throw(::com::sun::star::uno::RuntimeException
)
285 MutexGuard
aGuard( _pMgr
->_aComponentMutex
);
286 return (_nPos
< _pMgr
->_aProviders
.size());
288 //__________________________________________________________________________________________________
289 Any
EnumerationImpl::nextElement()
290 throw(::com::sun::star::container::NoSuchElementException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
)
292 MutexGuard
aGuard( _pMgr
->_aComponentMutex
);
293 if (_nPos
>= _pMgr
->_aProviders
.size())
295 throw NoSuchElementException(
296 OUString( RTL_CONSTASCII_USTRINGPARAM("there is no further element!") ),
297 (XWeak
*)(OWeakObject
*)this );
299 return makeAny( _pMgr
->_aProviders
[_nPos
++] );
302 //##################################################################################################
304 //__________________________________________________________________________________________________
305 ManagerImpl::ManagerImpl(
306 Reference
< XComponentContext
> const & xContext
, sal_Int32 nCacheSize
)
307 : WeakComponentImplHelper5
<
308 XServiceInfo
, XSet
, XHierarchicalNameAccess
,
309 XTypeDescriptionEnumerationAccess
, XInitialization
>( _aComponentMutex
)
310 , _xContext( xContext
)
311 , _aEventListener( this )
312 , _bCaching( sal_True
)
313 , _aElements( nCacheSize
)
315 ::g_moduleCount
.modCnt
.acquire( &::g_moduleCount
.modCnt
);
317 //__________________________________________________________________________________________________
318 ManagerImpl::~ManagerImpl()
320 OSL_ENSURE( _aProviders
.size() == 0, "### still providers left!" );
321 OSL_TRACE( "> TypeDescriptionManager shut down. <\n" );
322 ::g_moduleCount
.modCnt
.release( &::g_moduleCount
.modCnt
);
324 //__________________________________________________________________________________________________
325 void ManagerImpl::disposing()
327 // called on disposing the tdmgr instance (supposedly from context)
328 _bCaching
= sal_False
;
335 //__________________________________________________________________________________________________
336 void ManagerImpl::initialize(
337 const Sequence
< Any
> & args
)
338 throw (Exception
, RuntimeException
)
340 // additional providers
341 Any
const * pProviders
= args
.getConstArray();
342 for ( sal_Int32 nPos
= 0; nPos
< args
.getLength(); ++nPos
)
344 Reference
< XHierarchicalNameAccess
> xHA( pProviders
[ nPos
], UNO_QUERY
);
345 OSL_ENSURE( xHA
.is(), "### no td provider!" );
351 insert( makeAny( xHA
) );
353 catch (IllegalArgumentException
&)
356 catch (ElementExistException
&)
364 //__________________________________________________________________________________________________
365 OUString
ManagerImpl::getImplementationName()
366 throw(::com::sun::star::uno::RuntimeException
)
368 return stoc_bootstrap::tdmgr_getImplementationName();
370 //__________________________________________________________________________________________________
371 sal_Bool
ManagerImpl::supportsService( const OUString
& rServiceName
)
372 throw(::com::sun::star::uno::RuntimeException
)
374 const Sequence
< OUString
> & rSNL
= getSupportedServiceNames();
375 const OUString
* pArray
= rSNL
.getConstArray();
376 for ( sal_Int32 nPos
= rSNL
.getLength(); nPos
--; )
378 if (pArray
[nPos
] == rServiceName
)
383 //__________________________________________________________________________________________________
384 Sequence
< OUString
> ManagerImpl::getSupportedServiceNames()
385 throw(::com::sun::star::uno::RuntimeException
)
387 return stoc_bootstrap::tdmgr_getSupportedServiceNames();
391 //__________________________________________________________________________________________________
392 Type
ManagerImpl::getElementType()
393 throw(::com::sun::star::uno::RuntimeException
)
395 return ::getCppuType( (const Reference
< XHierarchicalNameAccess
> *)0 );
397 //__________________________________________________________________________________________________
398 sal_Bool
ManagerImpl::hasElements()
399 throw(::com::sun::star::uno::RuntimeException
)
401 MutexGuard
aGuard( _aComponentMutex
);
402 return (_aProviders
.size() > 0);
405 // XEnumerationAccess
406 //__________________________________________________________________________________________________
407 Reference
< XEnumeration
> ManagerImpl::createEnumeration()
408 throw(::com::sun::star::uno::RuntimeException
)
410 return new EnumerationImpl( this );
414 //__________________________________________________________________________________________________
415 sal_Bool SAL_CALL
ManagerImpl::has( const Any
& rElement
)
416 throw(::com::sun::star::uno::RuntimeException
)
418 Reference
< XHierarchicalNameAccess
> xElem
;
419 if (rElement
>>= xElem
)
421 MutexGuard
aGuard( _aComponentMutex
);
422 return (find( _aProviders
.begin(), _aProviders
.end(), xElem
) != _aProviders
.end());
427 //__________________________________________________________________________________________________
428 void SAL_CALL
ManagerImpl::insert( const Any
& rElement
)
429 throw(::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::container::ElementExistException
, ::com::sun::star::uno::RuntimeException
)
431 Reference
< XHierarchicalNameAccess
> xElem
;
432 if (! (rElement
>>= xElem
) || !xElem
.is())
434 throw IllegalArgumentException(
435 OUString( RTL_CONSTASCII_USTRINGPARAM("no valid type description provider given!") ),
436 (XWeak
*)(OWeakObject
*)this, 0 );
439 MutexGuard
aGuard( _aComponentMutex
);
440 if (find( _aProviders
.begin(), _aProviders
.end(), xElem
) != _aProviders
.end())
442 throw ElementExistException(
443 OUString( RTL_CONSTASCII_USTRINGPARAM("provider already inserted!") ),
444 (XWeak
*)(OWeakObject
*)this );
447 if (! _aProviders
.empty())
449 // check whether all types are compatible, if possible:
450 Reference
<reflection::XTypeDescriptionEnumerationAccess
> xTDEnumAccess(
452 OSL_ENSURE( xTDEnumAccess
.is(),
453 "### providers ought to implement "
454 "reflection::XTypeDescriptionEnumerationAccess!" );
455 if (xTDEnumAccess
.is())
460 TypeClass_ENUM
, TypeClass_TYPEDEF
, TypeClass_SEQUENCE
,
461 TypeClass_STRUCT
, TypeClass_EXCEPTION
,
462 /* TypeClass_UNION, TypeClass_ARRAY not supported */
465 TypeClass_INTERFACE_METHOD
, TypeClass_INTERFACE_ATTRIBUTE
,
466 TypeClass_PROPERTY
, TypeClass_CONSTANT
, TypeClass_CONSTANTS
,
469 Reference
<reflection::XTypeDescriptionEnumeration
> xTDEnum(
470 xTDEnumAccess
->createTypeDescriptionEnumeration(
471 OUString() /* all modules */,
472 Sequence
<TypeClass
>( ar
, ARLEN(ar
) ),
473 reflection::TypeDescriptionSearchDepth_INFINITE
) );
475 while (xTDEnum
->hasMoreElements())
477 Reference
<reflection::XTypeDescription
> xNewTD
;
480 xNewTD
= xTDEnum
->nextTypeDescription();
482 catch (container::NoSuchElementException
& exc
)
484 throw lang::IllegalArgumentException(
485 OUSTR("NoSuchElementException occured: ") +
486 exc
.Message
, static_cast<OWeakObject
*>(this),
492 OUString
newName( xNewTD
->getName() );
493 Reference
<reflection::XTypeDescription
> xExistingTD(
494 getByHierarchicalName( newName
), UNO_QUERY
);
495 OSL_ASSERT( xExistingTD
.is() );
496 // existing, check whether compatible:
497 if (xExistingTD
.is())
501 check( xNewTD
, xExistingTD
);
503 catch (IncompatibleTypeException
& exc
)
505 throw lang::IllegalArgumentException(
506 OUSTR("Rejecting types due to "
507 "incompatibility! ") + exc
.m_cause
,
508 static_cast<OWeakObject
*>(this), 0 );
512 catch (container::NoSuchElementException
&)
518 catch (reflection::NoSuchTypeNameException
& exc
)
520 throw lang::IllegalArgumentException(
521 OUSTR("NoSuchTypeNameException occured: ") + exc
.Message
,
522 static_cast<OWeakObject
*>(this), -1 /* unknown */ );
524 catch (reflection::InvalidTypeNameException
& exc
)
526 throw lang::IllegalArgumentException(
527 OUSTR("InvalidTypeNameException occured: ") + exc
.Message
,
528 static_cast<OWeakObject
*>(this), -1 /* unknown */ );
533 _aProviders
.push_back( xElem
);
534 Reference
< XComponent
> xComp( xElem
, UNO_QUERY
);
536 xComp
->addEventListener( &_aEventListener
);
538 //__________________________________________________________________________________________________
539 void SAL_CALL
ManagerImpl::remove( const Any
& rElement
)
540 throw(::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::container::NoSuchElementException
, ::com::sun::star::uno::RuntimeException
)
542 if (!rBHelper
.bDisposed
&& !rBHelper
.bInDispose
)
544 Reference
< XHierarchicalNameAccess
> xElem
;
545 if (! (rElement
>>= xElem
))
547 throw IllegalArgumentException(
548 OUString( RTL_CONSTASCII_USTRINGPARAM("no type description provider given!") ),
549 (XWeak
*)(OWeakObject
*)this, 0 );
552 MutexGuard
aGuard( _aComponentMutex
);
553 ProviderVector::iterator
iFind( find( _aProviders
.begin(), _aProviders
.end(), xElem
) );
554 if (iFind
== _aProviders
.end())
556 throw NoSuchElementException(
557 OUString( RTL_CONSTASCII_USTRINGPARAM("provider not found!") ),
558 (XWeak
*)(OWeakObject
*)this );
560 _aProviders
.erase( iFind
);
563 Reference
< XComponent
> xComp
;
564 if (rElement
>>= xComp
)
565 xComp
->removeEventListener( &_aEventListener
);
568 // XTypeDescriptionEnumerationAccess
569 //__________________________________________________________________________________________________
571 Reference
< XTypeDescriptionEnumeration
> SAL_CALL
572 ManagerImpl::createTypeDescriptionEnumeration(
573 const OUString
& moduleName
,
574 const Sequence
< TypeClass
> & types
,
575 TypeDescriptionSearchDepth depth
)
576 throw ( NoSuchTypeNameException
,
577 InvalidTypeNameException
,
580 MutexGuard
aGuard( _aComponentMutex
);
582 TDEnumerationAccessStack aStack
;
583 ProviderVector::const_iterator it
= _aProviders
.begin();
584 const ProviderVector::const_iterator end
= _aProviders
.end();
587 Reference
< XTypeDescriptionEnumerationAccess
>xEnumAccess(
589 OSL_ENSURE( xEnumAccess
.is(),
590 "### no XTypeDescriptionEnumerationAccess!" );
591 if ( xEnumAccess
.is() )
592 aStack
.push( xEnumAccess
);
597 return Reference
< XTypeDescriptionEnumeration
>(
598 new TypeDescriptionEnumerationImpl( moduleName
,
605 //##################################################################################################
606 //##################################################################################################
607 //##################################################################################################
610 //==================================================================================================
611 class SimpleTypeDescriptionImpl
612 : public WeakImplHelper1
< XTypeDescription
>
618 SimpleTypeDescriptionImpl( TypeClass eTC
, const OUString
& rName
)
624 virtual TypeClass SAL_CALL
getTypeClass() throw(::com::sun::star::uno::RuntimeException
);
625 virtual OUString SAL_CALL
getName() throw(::com::sun::star::uno::RuntimeException
);
629 //__________________________________________________________________________________________________
630 TypeClass
SimpleTypeDescriptionImpl::getTypeClass()
631 throw(::com::sun::star::uno::RuntimeException
)
635 //__________________________________________________________________________________________________
636 OUString
SimpleTypeDescriptionImpl::getName()
637 throw(::com::sun::star::uno::RuntimeException
)
642 //==================================================================================================
643 class SequenceTypeDescriptionImpl
644 : public WeakImplHelper1
< XIndirectTypeDescription
>
646 Reference
< XTypeDescription
> _xElementTD
;
649 SequenceTypeDescriptionImpl( const Reference
< XTypeDescription
> & xElementTD
)
650 : _xElementTD( xElementTD
)
654 virtual TypeClass SAL_CALL
getTypeClass() throw(::com::sun::star::uno::RuntimeException
);
655 virtual OUString SAL_CALL
getName() throw(::com::sun::star::uno::RuntimeException
);
657 // XIndirectTypeDescription
658 virtual Reference
< XTypeDescription
> SAL_CALL
getReferencedType() throw(::com::sun::star::uno::RuntimeException
);
662 //__________________________________________________________________________________________________
663 TypeClass
SequenceTypeDescriptionImpl::getTypeClass()
664 throw(::com::sun::star::uno::RuntimeException
)
666 return TypeClass_SEQUENCE
;
668 //__________________________________________________________________________________________________
669 OUString
SequenceTypeDescriptionImpl::getName()
670 throw(::com::sun::star::uno::RuntimeException
)
672 return (OUString( RTL_CONSTASCII_USTRINGPARAM("[]") ) + _xElementTD
->getName());
675 // XIndirectTypeDescription
676 //__________________________________________________________________________________________________
677 Reference
< XTypeDescription
> SequenceTypeDescriptionImpl::getReferencedType()
678 throw(::com::sun::star::uno::RuntimeException
)
683 //==================================================================================================
684 class ArrayTypeDescriptionImpl
685 : public WeakImplHelper1
< XArrayTypeDescription
>
687 Reference
< XTypeDescription
> _xElementTD
;
688 Mutex _aDimensionMutex
;
689 sal_Int32 _nDimensions
;
690 Sequence
< sal_Int32
> _seqDimensions
;
691 OUString _sDimensions
;
693 void initDimensions(const OUString
& rSDimensions
);
695 ArrayTypeDescriptionImpl( const Reference
< XTypeDescription
> & xElementTD
,
696 sal_Int32 nDimensions
, const OUString
& rSDimensions
)
697 : _xElementTD( xElementTD
)
698 , _nDimensions( nDimensions
)
699 , _seqDimensions( Sequence
< sal_Int32
>(nDimensions
) )
700 , _sDimensions( rSDimensions
)
702 initDimensions( rSDimensions
);
704 virtual ~ArrayTypeDescriptionImpl() {}
707 virtual TypeClass SAL_CALL
getTypeClass() throw(::com::sun::star::uno::RuntimeException
);
708 virtual OUString SAL_CALL
getName() throw(::com::sun::star::uno::RuntimeException
);
710 // XArrayTypeDescription
711 virtual Reference
< XTypeDescription
> SAL_CALL
getType() throw(::com::sun::star::uno::RuntimeException
);
712 virtual sal_Int32 SAL_CALL
getNumberOfDimensions() throw(::com::sun::star::uno::RuntimeException
);
713 virtual Sequence
< sal_Int32
> SAL_CALL
getDimensions() throw(::com::sun::star::uno::RuntimeException
);
715 //__________________________________________________________________________________________________
716 static sal_Int32
unicodeToInteger( sal_Int8 base
, const sal_Unicode
*s
)
719 sal_Int32 negative
= 0;
726 if (base
== 8 && *s
== '0')
728 else if (base
== 16 && *s
== '0' && (*(s
+ 1) == 'x' || *(s
+ 1) == 'X'))
733 if (*s
<= '9' && *s
>= '0')
734 r
= (r
* base
) + (*s
- '0');
735 else if (base
> 10 && *s
<= 'f' && *s
>= 'a')
736 r
= (r
* base
) + (*s
- 'a' + 10);
737 else if (base
> 10 && *s
<= 'F' && *s
>= 'A')
738 r
= (r
* base
) + (*s
- 'A' + 10);
742 if (negative
) r
*= -1;
745 //__________________________________________________________________________________________________
746 void ArrayTypeDescriptionImpl::initDimensions(const OUString
& rSDimensions
)
748 MutexGuard
aGuard( _aDimensionMutex
);
750 sal_Int32
* pDimensions
= _seqDimensions
.getArray();
751 OUString
tmp(rSDimensions
);
752 sal_Unicode
* p
= (sal_Unicode
*)tmp
.getStr()+1;
753 sal_Unicode
* pOffset
= p
;
754 sal_Int32 len
= tmp
.getLength() - 1 ;
765 pDimensions
[i
++] = unicodeToInteger(10, p
);
773 //__________________________________________________________________________________________________
774 TypeClass
ArrayTypeDescriptionImpl::getTypeClass()
775 throw(::com::sun::star::uno::RuntimeException
)
777 return TypeClass_ARRAY
;
779 //__________________________________________________________________________________________________
780 OUString
ArrayTypeDescriptionImpl::getName()
781 throw(::com::sun::star::uno::RuntimeException
)
783 return (_xElementTD
->getName() + _sDimensions
);
786 // XArrayTypeDescription
787 //__________________________________________________________________________________________________
788 Reference
< XTypeDescription
> ArrayTypeDescriptionImpl::getType()
789 throw(::com::sun::star::uno::RuntimeException
)
794 //__________________________________________________________________________________________________
795 sal_Int32
ArrayTypeDescriptionImpl::getNumberOfDimensions()
796 throw(::com::sun::star::uno::RuntimeException
)
801 //__________________________________________________________________________________________________
802 Sequence
< sal_Int32
> ArrayTypeDescriptionImpl::getDimensions()
803 throw(::com::sun::star::uno::RuntimeException
)
805 return _seqDimensions
;
808 //##################################################################################################
809 //##################################################################################################
810 //##################################################################################################
813 //__________________________________________________________________________________________________
814 inline Any
ManagerImpl::getSimpleType( const OUString
& rName
)
818 if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("string") ))
819 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_STRING
, rName
) );
820 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("long") ))
821 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_LONG
, rName
) );
822 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned long") ))
823 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_LONG
, rName
) );
824 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("boolean") ))
825 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_BOOLEAN
, rName
) );
826 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("char") ))
827 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_CHAR
, rName
) );
828 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("byte") ))
829 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_BYTE
, rName
) );
830 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("short") ))
831 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_SHORT
, rName
) );
832 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned short") ))
833 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_SHORT
, rName
) );
834 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("hyper") ))
835 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_HYPER
, rName
) );
836 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned hyper") ))
837 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_HYPER
, rName
) );
838 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("float") ))
839 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_FLOAT
, rName
) );
840 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("double") ))
841 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_DOUBLE
, rName
) );
842 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("any") ))
843 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_ANY
, rName
) );
844 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("void") ))
845 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_VOID
, rName
) );
846 else if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("type") ))
847 aRet
<<= Reference
< XTypeDescription
>( new SimpleTypeDescriptionImpl( TypeClass_TYPE
, rName
) );
854 Reference
< XTypeDescription
> resolveTypedefs(
855 Reference
< XTypeDescription
> const & type
)
857 Reference
< XTypeDescription
> resolved(type
);
858 while (resolved
->getTypeClass() == TypeClass_TYPEDEF
) {
859 resolved
= Reference
< XIndirectTypeDescription
>(
860 type
, UNO_QUERY_THROW
)->getReferencedType();
865 bool isNonVoidNonExceptionType(Reference
< XTypeDescription
> const & type
) {
866 switch (type
->getTypeClass()) {
867 case TypeClass_BOOLEAN
:
869 case TypeClass_SHORT
:
870 case TypeClass_UNSIGNED_SHORT
:
872 case TypeClass_UNSIGNED_LONG
:
873 case TypeClass_HYPER
:
874 case TypeClass_UNSIGNED_HYPER
:
875 case TypeClass_FLOAT
:
876 case TypeClass_DOUBLE
:
878 case TypeClass_STRING
:
881 case TypeClass_SEQUENCE
:
883 case TypeClass_STRUCT
:
884 case TypeClass_INTERFACE
:
892 class InstantiatedStruct
: public WeakImplHelper1
< XStructTypeDescription
> {
895 Reference
< XStructTypeDescription
> const & structType
,
896 std::vector
< Reference
< XTypeDescription
> > const & arguments
);
898 virtual TypeClass SAL_CALL
getTypeClass() throw (RuntimeException
)
899 { return TypeClass_STRUCT
; }
901 virtual OUString SAL_CALL
getName() throw (RuntimeException
);
903 virtual Reference
< XTypeDescription
> SAL_CALL
getBaseType()
904 throw (RuntimeException
)
905 { return m_struct
->getBaseType(); }
907 virtual Sequence
< Reference
< XTypeDescription
> > SAL_CALL
getMemberTypes()
908 throw (RuntimeException
);
910 virtual Sequence
< OUString
> SAL_CALL
getMemberNames()
911 throw (RuntimeException
)
912 { return m_struct
->getMemberNames(); }
914 virtual Sequence
< OUString
> SAL_CALL
getTypeParameters()
915 throw (RuntimeException
)
916 { return Sequence
< OUString
>(); }
918 virtual Sequence
< Reference
< XTypeDescription
> > SAL_CALL
919 getTypeArguments() throw (RuntimeException
)
920 { return m_arguments
; }
923 Reference
< XStructTypeDescription
> m_struct
;
924 Sequence
< Reference
< XTypeDescription
> > m_arguments
;
927 InstantiatedStruct::InstantiatedStruct(
928 Reference
< XStructTypeDescription
> const & structType
,
929 std::vector
< Reference
< XTypeDescription
> > const & arguments
):
930 m_struct(structType
),
931 m_arguments(static_cast< sal_Int32
>(arguments
.size()))
933 for (std::vector
< Reference
< XTypeDescription
> >::size_type i
= 0;
934 i
< arguments
.size(); ++i
)
936 m_arguments
[static_cast< sal_Int32
>(i
)] = arguments
[i
];
940 OUString
InstantiatedStruct::getName() throw (RuntimeException
) {
941 OUStringBuffer
buf(m_struct
->getName());
942 buf
.append(static_cast< sal_Unicode
>('<'));
943 for (sal_Int32 i
= 0; i
< m_arguments
.getLength(); ++i
) {
945 buf
.append(static_cast< sal_Unicode
>(','));
947 buf
.append(m_arguments
[i
]->getName());
949 buf
.append(static_cast< sal_Unicode
>('>'));
950 return buf
.makeStringAndClear();
953 Sequence
< Reference
< XTypeDescription
> > InstantiatedStruct::getMemberTypes()
954 throw (RuntimeException
)
956 Sequence
< Reference
< XTypeDescription
> > types(m_struct
->getMemberTypes());
957 for (sal_Int32 i
= 0; i
< types
.getLength(); ++i
) {
958 if (types
[i
]->getTypeClass() == TypeClass_UNKNOWN
) {
959 Sequence
< OUString
> parameters(m_struct
->getTypeParameters());
960 OSL_ASSERT(parameters
.getLength() == m_arguments
.getLength());
961 for (sal_Int32 j
= 0; j
< parameters
.getLength(); ++j
) {
962 if (parameters
[j
] == types
[i
]->getName()) {
963 types
[i
] = m_arguments
[j
];
974 Reference
< XTypeDescription
> ManagerImpl::getInstantiatedStruct(
975 OUString
const & name
)
977 sal_Int32 i
= name
.indexOf('<');
979 Reference
< XStructTypeDescription
> structType(
980 getByHierarchicalName(name
.copy(0, i
)), UNO_QUERY
);
981 std::vector
< Reference
< XTypeDescription
> > args
;
982 bool good
= structType
.is();
985 ++i
; // skip '<' or ','
987 for (sal_Int32 level
= 0; j
!= name
.getLength(); ++j
) {
988 sal_Unicode c
= name
[j
];
993 } else if (c
== '<') {
995 } else if (c
== '>') {
1002 if (j
!= name
.getLength()) {
1003 Reference
< XTypeDescription
> type(
1004 getByHierarchicalName(name
.copy(i
, j
- i
)), UNO_QUERY
);
1005 if (isNonVoidNonExceptionType(resolveTypedefs(type
))) {
1006 args
.push_back(type
);
1013 } while (i
!= name
.getLength() && name
[i
] != '>');
1014 good
= good
&& i
== name
.getLength() - 1
1015 && name
[i
] == '>' && !args
.empty();
1017 // args.size() cannot exceed SAL_MAX_INT32, as each argument consumes at
1018 // least one position within an rtl::OUString (which is no longer than
1022 != sal::static_int_cast
< sal_uInt32
>(
1023 structType
->getTypeParameters().getLength())))
1025 throw NoSuchElementException(name
, static_cast< OWeakObject
* >(this));
1027 return new InstantiatedStruct(structType
, args
);
1030 // XHierarchicalNameAccess
1031 //__________________________________________________________________________________________________
1032 Any
ManagerImpl::getByHierarchicalName( const OUString
& rName
)
1033 throw(::com::sun::star::container::NoSuchElementException
, ::com::sun::star::uno::RuntimeException
)
1037 aRet
= _aElements
.getValue( rName
);
1038 if (rName
.getLength() && !aRet
.hasValue())
1041 if (rName
[0] == '[') // test for sequence
1043 Reference
< XTypeDescription
> xElemType(
1044 getByHierarchicalName( rName
.copy( 2 ) ),
1046 aRet
<<= Reference
< XTypeDescription
>(
1047 new SequenceTypeDescriptionImpl( xElemType
) );
1049 else if (rName
[rName
.getLength()-1] == ']') // test for array
1051 sal_Int32 nIndex2
= 0, nTokens
= 0;
1052 do { rName
.getToken( 0, '[', nIndex2
); nTokens
++; } while( nIndex2
!= -1 );
1053 sal_Int32 nDims
= nTokens
- 1;
1054 sal_Int32 dimOffset
= rName
.indexOf('[');
1055 Reference
< XTypeDescription
> xElemType(
1056 getByHierarchicalName( rName
.copy( 0, dimOffset
) ),
1058 aRet
<<= Reference
< XTypeDescription
>(
1059 new ArrayTypeDescriptionImpl(
1060 xElemType
, nDims
, rName
.copy(dimOffset
) ) );
1062 // test for interface member names:
1063 else if ((nIndex
= rName
.indexOf( ':' )) >= 0)
1065 Reference
< XInterfaceTypeDescription
> xIfaceTD(
1066 getByHierarchicalName( rName
.copy( 0, nIndex
) ),
1068 const Sequence
< Reference
< XInterfaceMemberTypeDescription
> > &
1069 rMembers
= xIfaceTD
->getMembers();
1070 const Reference
< XInterfaceMemberTypeDescription
> * pMembers
=
1071 rMembers
.getConstArray();
1073 for ( sal_Int32 nPos
= rMembers
.getLength(); nPos
--; )
1075 if (rName
== pMembers
[nPos
]->getName())
1077 aRet
<<= Reference
< XTypeDescription
>(
1078 pMembers
[nPos
], UNO_QUERY_THROW
);
1082 if (! aRet
.hasValue())
1084 // member not found:
1085 throw NoSuchElementException(
1086 rName
, static_cast< OWeakObject
* >(this) );
1089 // test for instantiated polymorphic struct types:
1090 else if (rName
.indexOf('<') >= 0)
1092 aRet
<<= getInstantiatedStruct(rName
);
1094 else if (rName
.indexOf( '.' ) < 0) // test for simple/ build in types
1096 aRet
= getSimpleType( rName
);
1099 if (! aRet
.hasValue())
1101 // last, try callback chain
1102 for ( ProviderVector::const_iterator
iPos( _aProviders
.begin() );
1103 iPos
!= _aProviders
.end(); ++iPos
)
1107 if ((aRet
= (*iPos
)->getByHierarchicalName(
1108 rName
)).hasValue())
1113 catch (NoSuchElementException
&)
1120 if (_bCaching
&& aRet
.hasValue())
1121 _aElements
.setValue( rName
, aRet
);
1124 if (! aRet
.hasValue())
1126 throw NoSuchElementException(
1127 rName
, static_cast< OWeakObject
* >(this) );
1131 //__________________________________________________________________________________________________
1132 sal_Bool
ManagerImpl::hasByHierarchicalName( const OUString
& rName
)
1133 throw(::com::sun::star::uno::RuntimeException
)
1137 return getByHierarchicalName( rName
).hasValue();
1139 catch (NoSuchElementException
&)
1146 namespace stoc_bootstrap
1148 //==================================================================================================
1149 Reference
< XInterface
> SAL_CALL
ManagerImpl_create(
1150 Reference
< XComponentContext
> const & xContext
)
1151 SAL_THROW( (::com::sun::star::uno::Exception
) )
1153 sal_Int32 nCacheSize
= CACHE_SIZE
;
1154 if (xContext
.is()) {
1155 xContext
->getValueByName(
1157 RTL_CONSTASCII_USTRINGPARAM(
1158 "/implementations/" IMPLNAME
"/CacheSize"))) >>=
1162 return Reference
< XInterface
>( *new stoc_tdmgr::ManagerImpl( xContext
, nCacheSize
) );