Update ooo320-m1
[ooovba.git] / stoc / source / registry_tdprovider / tdiface.cxx
blob436205a611964fe436bb2a82fc9a1bbeb0a74361
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tdiface.cxx,v $
10 * $Revision: 1.15 $
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"
44 #include "base.hxx"
45 #include "functiondescription.hxx"
46 #include "methoddescription.hxx"
48 #include <memory>
49 #include <set>
51 namespace stoc_rdbtdp
54 //==================================================================================================
55 class InterfaceMethodImpl : public WeakImplHelper1< XInterfaceMethodTypeDescription >
57 stoc::registry_tdprovider::MethodDescription _desc;
59 Reference< XHierarchicalNameAccess > _xTDMgr;
61 OUString _aTypeName;
63 OUString _aReturnType;
64 Reference< XTypeDescription > _xReturnTD;
66 sal_Bool _bIsOneWay;
67 sal_Int32 _nPosition;
69 public:
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,
76 sal_Bool bIsOneWay,
77 sal_Int32 nPosition )
78 : _desc(xTDMgr, rMemberName, rBytes, nMethodIndex)
79 , _xTDMgr( xTDMgr )
80 , _aTypeName( rTypeName )
81 , _aReturnType( rReturnType )
82 , _bIsOneWay( bIsOneWay )
83 , _nPosition( nPosition )
85 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
87 virtual ~InterfaceMethodImpl();
89 // XTypeDescription
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 );
110 // XTypeDescription
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)
121 return _aTypeName;
124 // XInterfaceMemberTypeDescription
125 //__________________________________________________________________________________________________
126 sal_Int32 InterfaceMethodImpl::getPosition()
127 throw(::com::sun::star::uno::RuntimeException)
129 return _nPosition;
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;
147 return _xReturnTD;
150 catch (NoSuchElementException &)
153 // never try again, if no td was found
154 _aReturnType = OUString();
156 return _xReturnTD;
158 //__________________________________________________________________________________________________
159 sal_Bool InterfaceMethodImpl::isOneway()
160 throw(::com::sun::star::uno::RuntimeException)
162 return _bIsOneWay;
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) {
171 s2[i] = s1[i].get();
173 return s2;
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) {
183 s2[i] = s1[i].get();
185 return s2;
189 //##################################################################################################
190 //##################################################################################################
191 //##################################################################################################
194 //==================================================================================================
195 class InterfaceAttributeImpl : public WeakImplHelper1< XInterfaceAttributeTypeDescription2 >
197 Reference< XHierarchicalNameAccess > _xTDMgr;
199 OUString _aTypeName;
200 OUString _aMemberName;
202 OUString _aMemberTypeName;
203 Reference< XTypeDescription > _xMemberTD;
205 sal_Bool _bReadOnly;
206 sal_Bool _bBound;
207 sal_Int32 _nPosition;
209 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > _getter;
210 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > _setter;
212 public:
213 InterfaceAttributeImpl(
214 const Reference< XHierarchicalNameAccess > & xTDMgr,
215 const OUString & rTypeName,
216 const OUString & rMemberName,
217 const OUString & rMemberTypeName,
218 sal_Bool bReadOnly,
219 sal_Bool bBound,
220 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > &
221 getter,
222 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > &
223 setter,
224 sal_Int32 nPosition )
225 : _xTDMgr( xTDMgr )
226 , _aTypeName( rTypeName )
227 , _aMemberName( rMemberName )
228 , _aMemberTypeName( rMemberTypeName )
229 , _bReadOnly( bReadOnly )
230 , _bBound( bBound )
231 , _nPosition( nPosition )
232 , _getter( getter )
233 , _setter( setter )
235 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
237 virtual ~InterfaceAttributeImpl();
239 // XTypeDescription
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)
252 { return _bBound; }
254 virtual Sequence< Reference< XCompoundTypeDescription > > SAL_CALL
255 getGetExceptions() throw (RuntimeException)
257 if (_getter.get() != 0) {
258 return _getter->getExceptions();
259 } else {
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();
269 } else {
270 return Sequence< Reference< XCompoundTypeDescription > >();
275 InterfaceAttributeImpl::~InterfaceAttributeImpl()
277 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
279 // XTypeDescription
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)
290 return _aTypeName;
293 // XInterfaceMemberTypeDescription
294 //__________________________________________________________________________________________________
295 OUString InterfaceAttributeImpl::getMemberName()
296 throw(::com::sun::star::uno::RuntimeException)
298 return _aMemberName;
300 //__________________________________________________________________________________________________
301 sal_Int32 InterfaceAttributeImpl::getPosition()
302 throw(::com::sun::star::uno::RuntimeException)
304 return _nPosition;
307 // XInterfaceAttributeTypeDescription2
308 //__________________________________________________________________________________________________
309 sal_Bool InterfaceAttributeImpl::isReadOnly()
310 throw(::com::sun::star::uno::RuntimeException)
312 return _bReadOnly;
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;
328 return _xMemberTD;
331 catch (NoSuchElementException &)
334 // never try again, if no td was found
335 _aMemberTypeName = OUString();
337 return _xMemberTD;
341 //##################################################################################################
342 //##################################################################################################
343 //##################################################################################################
345 void InterfaceTypeDescriptionImpl::checkInterfaceType(
346 Reference< XTypeDescription > const & type)
348 if (resolveTypedefs(type)->getTypeClass() != TypeClass_INTERFACE) {
349 throw RuntimeException(
350 OUString(
351 RTL_CONSTASCII_USTRINGPARAM(
352 "Interface base is not an interface type")),
353 static_cast< OWeakObject * >(this));
357 namespace {
359 class BaseOffset {
360 public:
361 BaseOffset(Reference< XInterfaceTypeDescription2 > const & desc);
363 sal_Int32 get() const { return offset; }
365 private:
366 void calculateBases(Reference< XInterfaceTypeDescription2 > const & desc);
368 void calculate(Reference< XInterfaceTypeDescription2 > const & desc);
370 std::set< rtl::OUString > set;
371 sal_Int32 offset;
374 BaseOffset::BaseOffset(Reference< XInterfaceTypeDescription2 > const & desc) {
375 offset = 0;
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) {
384 calculate(
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 )
406 : _xTDMgr( xTDMgr )
407 , _aBytes( rBytes )
408 , _aName( rName )
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 );
422 // XTypeDescription
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)
433 return _aName;
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)
448 return Uik();
450 //__________________________________________________________________________________________________
451 Sequence< Reference< XInterfaceMemberTypeDescription > > InterfaceTypeDescriptionImpl::getMembers()
452 throw(::com::sun::star::uno::RuntimeException)
454 osl::MutexGuard guard(getMutex());
455 if (!_membersInit) {
456 _nBaseOffset = BaseOffset(this).get();
457 typereg::Reader reader(
458 _aBytes.getConstArray(), _aBytes.getLength(), false,
459 TYPEREG_VERSION_1);
460 sal_Int32 count = 0;
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)
467 ++count;
470 sal_uInt16 fieldCount = reader.getFieldCount();
471 count += fieldCount;
472 _members.realloc(count);
473 sal_Int32 index = 0;
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 >
481 getter;
482 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription >
483 setter;
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);
489 getter.reset(
490 new stoc::registry_tdprovider::FunctionDescription(
491 _xTDMgr, _aBytes, j));
492 break;
494 case RT_MODE_ATTRIBUTE_SET:
495 OSL_ASSERT(setter.get() == 0);
496 setter.reset(
497 new stoc::registry_tdprovider::FunctionDescription(
498 _xTDMgr, _aBytes, j));
499 break;
501 default:
502 OSL_ASSERT(false);
503 break;
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);
513 ++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);
528 ++index;
531 _membersInit = true;
533 return _members;
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) {
542 try {
543 _xTDMgr->getByHierarchicalName(_aBaseTypes[i]) >>= tds[i];
544 } catch (NoSuchElementException & e) {
545 throw RuntimeException(
546 (OUString(
547 RTL_CONSTASCII_USTRINGPARAM(
548 "com.sun.star.container.NoSuchElementException: "))
549 + e.Message),
550 static_cast< OWeakObject * >(this));
552 OSL_ASSERT(tds[i].is());
553 checkInterfaceType(tds[i]);
555 _xBaseTDs = tds;
557 return _xBaseTDs;
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) {
569 try {
570 _xTDMgr->getByHierarchicalName(_aOptionalBaseTypes[i])
571 >>= tds[i];
572 } catch (NoSuchElementException & e) {
573 throw RuntimeException(
574 (OUString(
575 RTL_CONSTASCII_USTRINGPARAM(
576 "com.sun.star.container.NoSuchElementException: "))
577 + e.Message),
578 static_cast< OWeakObject * >(this));
580 OSL_ASSERT(tds[i].is());
581 checkInterfaceType(tds[i]);
583 _xOptionalBaseTDs = tds;
585 return _xOptionalBaseTDs;