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: tdiface.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 <rtl/ustrbuf.hxx>
35 #include "registry/reader.hxx"
36 #include "registry/version.h"
38 #include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp>
39 #include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp>
40 #include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp>
41 #include <com/sun/star/reflection/XMethodParameter.hpp>
42 #include <com/sun/star/reflection/XParameter.hpp>
43 #include "com/sun/star/uno/RuntimeException.hpp"
45 #include "functiondescription.hxx"
46 #include "methoddescription.hxx"
54 //==================================================================================================
55 class InterfaceMethodImpl
: public WeakImplHelper1
< XInterfaceMethodTypeDescription
>
57 stoc::registry_tdprovider::MethodDescription _desc
;
59 Reference
< XHierarchicalNameAccess
> _xTDMgr
;
63 OUString _aReturnType
;
64 Reference
< XTypeDescription
> _xReturnTD
;
70 InterfaceMethodImpl( const Reference
< XHierarchicalNameAccess
> & xTDMgr
,
71 const OUString
& rTypeName
,
72 const OUString
& rMemberName
,
73 const OUString
& rReturnType
,
74 const Sequence
< sal_Int8
> & rBytes
,
75 sal_uInt16 nMethodIndex
,
78 : _desc(xTDMgr
, rMemberName
, rBytes
, nMethodIndex
)
80 , _aTypeName( rTypeName
)
81 , _aReturnType( rReturnType
)
82 , _bIsOneWay( bIsOneWay
)
83 , _nPosition( nPosition
)
85 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
87 virtual ~InterfaceMethodImpl();
90 virtual TypeClass SAL_CALL
getTypeClass() throw(::com::sun::star::uno::RuntimeException
);
91 virtual OUString SAL_CALL
getName() throw(::com::sun::star::uno::RuntimeException
);
93 // XInterfaceMemberTypeDescription
94 virtual OUString SAL_CALL
getMemberName() throw(::com::sun::star::uno::RuntimeException
)
95 { return _desc
.getName(); }
96 virtual sal_Int32 SAL_CALL
getPosition() throw(::com::sun::star::uno::RuntimeException
);
98 // XInterfaceMethodTypeDescription
99 virtual Reference
< XTypeDescription
> SAL_CALL
getReturnType() throw(::com::sun::star::uno::RuntimeException
);
100 virtual sal_Bool SAL_CALL
isOneway() throw(::com::sun::star::uno::RuntimeException
);
101 virtual Sequence
< Reference
< XMethodParameter
> > SAL_CALL
getParameters() throw(::com::sun::star::uno::RuntimeException
);
102 virtual Sequence
< Reference
< XTypeDescription
> > SAL_CALL
getExceptions() throw(::com::sun::star::uno::RuntimeException
);
104 //__________________________________________________________________________________________________
105 InterfaceMethodImpl::~InterfaceMethodImpl()
107 g_moduleCount
.modCnt
.release( &g_moduleCount
.modCnt
);
111 //__________________________________________________________________________________________________
112 TypeClass
InterfaceMethodImpl::getTypeClass()
113 throw(::com::sun::star::uno::RuntimeException
)
115 return TypeClass_INTERFACE_METHOD
;
117 //__________________________________________________________________________________________________
118 OUString
InterfaceMethodImpl::getName()
119 throw(::com::sun::star::uno::RuntimeException
)
124 // XInterfaceMemberTypeDescription
125 //__________________________________________________________________________________________________
126 sal_Int32
InterfaceMethodImpl::getPosition()
127 throw(::com::sun::star::uno::RuntimeException
)
132 // XInterfaceMethodTypeDescription
133 //__________________________________________________________________________________________________
134 Reference
<XTypeDescription
> InterfaceMethodImpl::getReturnType()
135 throw(::com::sun::star::uno::RuntimeException
)
137 if (!_xReturnTD
.is() && _aReturnType
.getLength())
141 Reference
< XTypeDescription
> xReturnTD
;
142 if (_xTDMgr
->getByHierarchicalName( _aReturnType
) >>= xReturnTD
)
144 MutexGuard
aGuard( getMutex() );
145 if (! _xReturnTD
.is())
146 _xReturnTD
= xReturnTD
;
150 catch (NoSuchElementException
&)
153 // never try again, if no td was found
154 _aReturnType
= OUString();
158 //__________________________________________________________________________________________________
159 sal_Bool
InterfaceMethodImpl::isOneway()
160 throw(::com::sun::star::uno::RuntimeException
)
164 //__________________________________________________________________________________________________
165 Sequence
<Reference
<XMethodParameter
> > InterfaceMethodImpl::getParameters()
166 throw(::com::sun::star::uno::RuntimeException
)
168 Sequence
< Reference
< XParameter
> > s1(_desc
.getParameters());
169 Sequence
< Reference
< XMethodParameter
> > s2(s1
.getLength());
170 for (sal_Int32 i
= 0; i
< s1
.getLength(); ++i
) {
175 //__________________________________________________________________________________________________
176 Sequence
<Reference
<XTypeDescription
> > InterfaceMethodImpl::getExceptions()
177 throw(::com::sun::star::uno::RuntimeException
)
179 Sequence
< Reference
< XCompoundTypeDescription
> > s1(
180 _desc
.getExceptions());
181 Sequence
< Reference
< XTypeDescription
> > s2(s1
.getLength());
182 for (sal_Int32 i
= 0; i
< s1
.getLength(); ++i
) {
189 //##################################################################################################
190 //##################################################################################################
191 //##################################################################################################
194 //==================================================================================================
195 class InterfaceAttributeImpl
: public WeakImplHelper1
< XInterfaceAttributeTypeDescription2
>
197 Reference
< XHierarchicalNameAccess
> _xTDMgr
;
200 OUString _aMemberName
;
202 OUString _aMemberTypeName
;
203 Reference
< XTypeDescription
> _xMemberTD
;
207 sal_Int32 _nPosition
;
209 std::auto_ptr
< stoc::registry_tdprovider::FunctionDescription
> _getter
;
210 std::auto_ptr
< stoc::registry_tdprovider::FunctionDescription
> _setter
;
213 InterfaceAttributeImpl(
214 const Reference
< XHierarchicalNameAccess
> & xTDMgr
,
215 const OUString
& rTypeName
,
216 const OUString
& rMemberName
,
217 const OUString
& rMemberTypeName
,
220 std::auto_ptr
< stoc::registry_tdprovider::FunctionDescription
> &
222 std::auto_ptr
< stoc::registry_tdprovider::FunctionDescription
> &
224 sal_Int32 nPosition
)
226 , _aTypeName( rTypeName
)
227 , _aMemberName( rMemberName
)
228 , _aMemberTypeName( rMemberTypeName
)
229 , _bReadOnly( bReadOnly
)
231 , _nPosition( nPosition
)
235 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
237 virtual ~InterfaceAttributeImpl();
240 virtual TypeClass SAL_CALL
getTypeClass() throw(::com::sun::star::uno::RuntimeException
);
241 virtual OUString SAL_CALL
getName() throw(::com::sun::star::uno::RuntimeException
);
243 // XInterfaceMemberTypeDescription
244 virtual OUString SAL_CALL
getMemberName() throw(::com::sun::star::uno::RuntimeException
);
245 virtual sal_Int32 SAL_CALL
getPosition() throw(::com::sun::star::uno::RuntimeException
);
247 // XInterfaceAttributeTypeDescription2
248 virtual sal_Bool SAL_CALL
isReadOnly() throw(::com::sun::star::uno::RuntimeException
);
249 virtual Reference
< XTypeDescription
> SAL_CALL
getType() throw(::com::sun::star::uno::RuntimeException
);
251 virtual sal_Bool SAL_CALL
isBound() throw (RuntimeException
)
254 virtual Sequence
< Reference
< XCompoundTypeDescription
> > SAL_CALL
255 getGetExceptions() throw (RuntimeException
)
257 if (_getter
.get() != 0) {
258 return _getter
->getExceptions();
260 return Sequence
< Reference
< XCompoundTypeDescription
> >();
264 virtual Sequence
< Reference
< XCompoundTypeDescription
> > SAL_CALL
265 getSetExceptions() throw (RuntimeException
)
267 if (_setter
.get() != 0) {
268 return _setter
->getExceptions();
270 return Sequence
< Reference
< XCompoundTypeDescription
> >();
275 InterfaceAttributeImpl::~InterfaceAttributeImpl()
277 g_moduleCount
.modCnt
.release( &g_moduleCount
.modCnt
);
280 //__________________________________________________________________________________________________
281 TypeClass
InterfaceAttributeImpl::getTypeClass()
282 throw(::com::sun::star::uno::RuntimeException
)
284 return TypeClass_INTERFACE_ATTRIBUTE
;
286 //__________________________________________________________________________________________________
287 OUString
InterfaceAttributeImpl::getName()
288 throw(::com::sun::star::uno::RuntimeException
)
293 // XInterfaceMemberTypeDescription
294 //__________________________________________________________________________________________________
295 OUString
InterfaceAttributeImpl::getMemberName()
296 throw(::com::sun::star::uno::RuntimeException
)
300 //__________________________________________________________________________________________________
301 sal_Int32
InterfaceAttributeImpl::getPosition()
302 throw(::com::sun::star::uno::RuntimeException
)
307 // XInterfaceAttributeTypeDescription2
308 //__________________________________________________________________________________________________
309 sal_Bool
InterfaceAttributeImpl::isReadOnly()
310 throw(::com::sun::star::uno::RuntimeException
)
314 //__________________________________________________________________________________________________
315 Reference
<XTypeDescription
> InterfaceAttributeImpl::getType()
316 throw(::com::sun::star::uno::RuntimeException
)
318 if (!_xMemberTD
.is() && _aMemberTypeName
.getLength())
322 Reference
< XTypeDescription
> xMemberTD
;
323 if (_xTDMgr
->getByHierarchicalName( _aMemberTypeName
) >>= xMemberTD
)
325 MutexGuard
aGuard( getMutex() );
326 if (! _xMemberTD
.is())
327 _xMemberTD
= xMemberTD
;
331 catch (NoSuchElementException
&)
334 // never try again, if no td was found
335 _aMemberTypeName
= OUString();
341 //##################################################################################################
342 //##################################################################################################
343 //##################################################################################################
345 void InterfaceTypeDescriptionImpl::checkInterfaceType(
346 Reference
< XTypeDescription
> const & type
)
348 if (resolveTypedefs(type
)->getTypeClass() != TypeClass_INTERFACE
) {
349 throw RuntimeException(
351 RTL_CONSTASCII_USTRINGPARAM(
352 "Interface base is not an interface type")),
353 static_cast< OWeakObject
* >(this));
361 BaseOffset(Reference
< XInterfaceTypeDescription2
> const & desc
);
363 sal_Int32
get() const { return offset
; }
366 void calculateBases(Reference
< XInterfaceTypeDescription2
> const & desc
);
368 void calculate(Reference
< XInterfaceTypeDescription2
> const & desc
);
370 std::set
< rtl::OUString
> set
;
374 BaseOffset::BaseOffset(Reference
< XInterfaceTypeDescription2
> const & desc
) {
376 calculateBases(desc
);
379 void BaseOffset::calculateBases(
380 Reference
< XInterfaceTypeDescription2
> const & desc
)
382 Sequence
< Reference
< XTypeDescription
> > bases(desc
->getBaseTypes());
383 for (sal_Int32 i
= 0; i
< bases
.getLength(); ++i
) {
385 Reference
< XInterfaceTypeDescription2
>(
386 resolveTypedefs(bases
[i
]), UNO_QUERY_THROW
));
390 void BaseOffset::calculate(Reference
< XInterfaceTypeDescription2
> const & desc
)
392 if (set
.insert(desc
->getName()).second
) {
393 calculateBases(desc
);
394 offset
+= desc
->getMembers().getLength();
400 //__________________________________________________________________________________________________
401 InterfaceTypeDescriptionImpl::InterfaceTypeDescriptionImpl(
402 const Reference
< XHierarchicalNameAccess
> & xTDMgr
,
403 const OUString
& rName
, const Sequence
< OUString
> & rBaseTypes
,
404 const Sequence
< OUString
> & rOptionalBaseTypes
,
405 const Sequence
< sal_Int8
> & rBytes
, bool published
)
409 , _aBaseTypes( rBaseTypes
)
410 , _aOptionalBaseTypes( rOptionalBaseTypes
)
411 , _membersInit( false )
412 , _published( published
)
414 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
416 //__________________________________________________________________________________________________
417 InterfaceTypeDescriptionImpl::~InterfaceTypeDescriptionImpl()
419 g_moduleCount
.modCnt
.release( &g_moduleCount
.modCnt
);
423 //__________________________________________________________________________________________________
424 TypeClass
InterfaceTypeDescriptionImpl::getTypeClass()
425 throw(::com::sun::star::uno::RuntimeException
)
427 return TypeClass_INTERFACE
;
429 //__________________________________________________________________________________________________
430 OUString
InterfaceTypeDescriptionImpl::getName()
431 throw(::com::sun::star::uno::RuntimeException
)
436 // XInterfaceTypeDescription2
437 //__________________________________________________________________________________________________
438 Reference
< XTypeDescription
> InterfaceTypeDescriptionImpl::getBaseType()
439 throw(::com::sun::star::uno::RuntimeException
)
441 Sequence
< Reference
< XTypeDescription
> > aBaseTypes(getBaseTypes());
442 return aBaseTypes
.getLength() >= 1 ? aBaseTypes
[0] : 0;
444 //__________________________________________________________________________________________________
445 Uik SAL_CALL
InterfaceTypeDescriptionImpl::getUik()
446 throw(::com::sun::star::uno::RuntimeException
)
450 //__________________________________________________________________________________________________
451 Sequence
< Reference
< XInterfaceMemberTypeDescription
> > InterfaceTypeDescriptionImpl::getMembers()
452 throw(::com::sun::star::uno::RuntimeException
)
454 osl::MutexGuard
guard(getMutex());
456 _nBaseOffset
= BaseOffset(this).get();
457 typereg::Reader
reader(
458 _aBytes
.getConstArray(), _aBytes
.getLength(), false,
461 sal_uInt16 methodCount
= reader
.getMethodCount();
462 {for (sal_uInt16 i
= 0; i
< methodCount
; ++i
) {
463 RTMethodMode flags
= reader
.getMethodFlags(i
);
464 if (flags
!= RT_MODE_ATTRIBUTE_GET
465 && flags
!= RT_MODE_ATTRIBUTE_SET
)
470 sal_uInt16 fieldCount
= reader
.getFieldCount();
472 _members
.realloc(count
);
474 {for (sal_uInt16 i
= 0; i
< fieldCount
; ++i
) {
475 rtl::OUString
name(reader
.getFieldName(i
));
476 rtl::OUStringBuffer
typeName(getName());
477 typeName
.appendAscii(RTL_CONSTASCII_STRINGPARAM("::"));
478 typeName
.append(name
);
479 RTFieldAccess flags
= reader
.getFieldFlags(i
);
480 std::auto_ptr
< stoc::registry_tdprovider::FunctionDescription
>
482 std::auto_ptr
< stoc::registry_tdprovider::FunctionDescription
>
484 for (sal_uInt16 j
= 0; j
< methodCount
; ++j
) {
485 if (reader
.getMethodName(j
) == name
) {
486 switch (reader
.getMethodFlags(j
)) {
487 case RT_MODE_ATTRIBUTE_GET
:
488 OSL_ASSERT(getter
.get() == 0);
490 new stoc::registry_tdprovider::FunctionDescription(
491 _xTDMgr
, _aBytes
, j
));
494 case RT_MODE_ATTRIBUTE_SET
:
495 OSL_ASSERT(setter
.get() == 0);
497 new stoc::registry_tdprovider::FunctionDescription(
498 _xTDMgr
, _aBytes
, j
));
507 _members
[index
] = new InterfaceAttributeImpl(
508 _xTDMgr
, typeName
.makeStringAndClear(), name
,
509 reader
.getFieldTypeName(i
).replace('/', '.'),
510 (flags
& RT_ACCESS_READONLY
) != 0,
511 (flags
& RT_ACCESS_BOUND
) != 0, getter
, setter
,
512 _nBaseOffset
+ index
);
515 {for (sal_uInt16 i
= 0; i
< methodCount
; ++i
) {
516 RTMethodMode flags
= reader
.getMethodFlags(i
);
517 if (flags
!= RT_MODE_ATTRIBUTE_GET
518 && flags
!= RT_MODE_ATTRIBUTE_SET
)
520 rtl::OUString
name(reader
.getMethodName(i
));
521 rtl::OUStringBuffer
typeName(getName());
522 typeName
.appendAscii(RTL_CONSTASCII_STRINGPARAM("::"));
523 typeName
.append(name
);
524 _members
[index
] = new InterfaceMethodImpl(
525 _xTDMgr
, typeName
.makeStringAndClear(), name
,
526 reader
.getMethodReturnTypeName(i
).replace('/', '.'),
527 _aBytes
, i
, flags
== RT_MODE_ONEWAY
, _nBaseOffset
+ index
);
536 Sequence
< Reference
< XTypeDescription
> >
537 InterfaceTypeDescriptionImpl::getBaseTypes() throw (RuntimeException
) {
538 MutexGuard
guard(getMutex());
539 if (_xBaseTDs
.getLength() == 0 && _aBaseTypes
.getLength() != 0) {
540 Sequence
< Reference
< XTypeDescription
> > tds(_aBaseTypes
.getLength());
541 for (sal_Int32 i
= 0; i
< _aBaseTypes
.getLength(); ++i
) {
543 _xTDMgr
->getByHierarchicalName(_aBaseTypes
[i
]) >>= tds
[i
];
544 } catch (NoSuchElementException
& e
) {
545 throw RuntimeException(
547 RTL_CONSTASCII_USTRINGPARAM(
548 "com.sun.star.container.NoSuchElementException: "))
550 static_cast< OWeakObject
* >(this));
552 OSL_ASSERT(tds
[i
].is());
553 checkInterfaceType(tds
[i
]);
560 Sequence
< Reference
< XTypeDescription
> >
561 InterfaceTypeDescriptionImpl::getOptionalBaseTypes() throw (RuntimeException
) {
562 MutexGuard
guard(getMutex());
563 if (_xOptionalBaseTDs
.getLength() == 0
564 && _aOptionalBaseTypes
.getLength() != 0)
566 Sequence
< Reference
< XTypeDescription
> > tds(
567 _aOptionalBaseTypes
.getLength());
568 for (sal_Int32 i
= 0; i
< _aOptionalBaseTypes
.getLength(); ++i
) {
570 _xTDMgr
->getByHierarchicalName(_aOptionalBaseTypes
[i
])
572 } catch (NoSuchElementException
& e
) {
573 throw RuntimeException(
575 RTL_CONSTASCII_USTRINGPARAM(
576 "com.sun.star.container.NoSuchElementException: "))
578 static_cast< OWeakObject
* >(this));
580 OSL_ASSERT(tds
[i
].is());
581 checkInterfaceType(tds
[i
]);
583 _xOptionalBaseTDs
= tds
;
585 return _xOptionalBaseTDs
;