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 <rtl/ustrbuf.hxx>
28 #include "registry/reader.hxx"
29 #include "registry/version.h"
30
31 #include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp>
32 #include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp>
33 #include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp>
34 #include <com/sun/star/reflection/XMethodParameter.hpp>
35 #include <com/sun/star/reflection/XParameter.hpp>
36 #include "com/sun/star/uno/RuntimeException.hpp"
37 #include "base.hxx"
38 #include "functiondescription.hxx"
39 #include "methoddescription.hxx"
40
41 #include <memory>
42 #include <set>
43
44 namespace stoc_rdbtdp
45 {
46
47 //==================================================================================================
48 class InterfaceMethodImpl : public WeakImplHelper1< XInterfaceMethodTypeDescription >
49 {
50 stoc::registry_tdprovider::MethodDescription _desc;
51
52 Reference< XHierarchicalNameAccess > _xTDMgr;
53
54 OUString _aTypeName;
55
56 OUString _aReturnType;
57 Reference< XTypeDescription > _xReturnTD;
58
59 sal_Bool _bIsOneWay;
60 sal_Int32 _nPosition;
61
62 public:
InterfaceMethodImpl(const Reference<XHierarchicalNameAccess> & xTDMgr,const OUString & rTypeName,const OUString & rMemberName,const OUString & rReturnType,const Sequence<sal_Int8> & rBytes,sal_uInt16 nMethodIndex,sal_Bool bIsOneWay,sal_Int32 nPosition)63 InterfaceMethodImpl( const Reference< XHierarchicalNameAccess > & xTDMgr,
64 const OUString & rTypeName,
65 const OUString & rMemberName,
66 const OUString & rReturnType,
67 const Sequence< sal_Int8 > & rBytes,
68 sal_uInt16 nMethodIndex,
69 sal_Bool bIsOneWay,
70 sal_Int32 nPosition )
71 : _desc(xTDMgr, rMemberName, rBytes, nMethodIndex)
72 , _xTDMgr( xTDMgr )
73 , _aTypeName( rTypeName )
74 , _aReturnType( rReturnType )
75 , _bIsOneWay( bIsOneWay )
76 , _nPosition( nPosition )
77 {
78 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
79 }
80 virtual ~InterfaceMethodImpl();
81
82 // XTypeDescription
83 virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
84 virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
85
86 // XInterfaceMemberTypeDescription
getMemberName()87 virtual OUString SAL_CALL getMemberName() throw(::com::sun::star::uno::RuntimeException)
88 { return _desc.getName(); }
89 virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException);
90
91 // XInterfaceMethodTypeDescription
92 virtual Reference< XTypeDescription > SAL_CALL getReturnType() throw(::com::sun::star::uno::RuntimeException);
93 virtual sal_Bool SAL_CALL isOneway() throw(::com::sun::star::uno::RuntimeException);
94 virtual Sequence< Reference< XMethodParameter > > SAL_CALL getParameters() throw(::com::sun::star::uno::RuntimeException);
95 virtual Sequence< Reference< XTypeDescription > > SAL_CALL getExceptions() throw(::com::sun::star::uno::RuntimeException);
96 };
97 //__________________________________________________________________________________________________
~InterfaceMethodImpl()98 InterfaceMethodImpl::~InterfaceMethodImpl()
99 {
100 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
101 }
102
103 // XTypeDescription
104 //__________________________________________________________________________________________________
getTypeClass()105 TypeClass InterfaceMethodImpl::getTypeClass()
106 throw(::com::sun::star::uno::RuntimeException)
107 {
108 return TypeClass_INTERFACE_METHOD;
109 }
110 //__________________________________________________________________________________________________
getName()111 OUString InterfaceMethodImpl::getName()
112 throw(::com::sun::star::uno::RuntimeException)
113 {
114 return _aTypeName;
115 }
116
117 // XInterfaceMemberTypeDescription
118 //__________________________________________________________________________________________________
getPosition()119 sal_Int32 InterfaceMethodImpl::getPosition()
120 throw(::com::sun::star::uno::RuntimeException)
121 {
122 return _nPosition;
123 }
124
125 // XInterfaceMethodTypeDescription
126 //__________________________________________________________________________________________________
getReturnType()127 Reference<XTypeDescription > InterfaceMethodImpl::getReturnType()
128 throw(::com::sun::star::uno::RuntimeException)
129 {
130 if (!_xReturnTD.is() && _aReturnType.getLength())
131 {
132 try
133 {
134 Reference< XTypeDescription > xReturnTD;
135 if (_xTDMgr->getByHierarchicalName( _aReturnType ) >>= xReturnTD)
136 {
137 MutexGuard aGuard( getMutex() );
138 if (! _xReturnTD.is())
139 _xReturnTD = xReturnTD;
140 return _xReturnTD;
141 }
142 }
143 catch (NoSuchElementException &)
144 {
145 }
146 // never try again, if no td was found
147 _aReturnType = OUString();
148 }
149 return _xReturnTD;
150 }
151 //__________________________________________________________________________________________________
isOneway()152 sal_Bool InterfaceMethodImpl::isOneway()
153 throw(::com::sun::star::uno::RuntimeException)
154 {
155 return _bIsOneWay;
156 }
157 //__________________________________________________________________________________________________
getParameters()158 Sequence<Reference<XMethodParameter > > InterfaceMethodImpl::getParameters()
159 throw(::com::sun::star::uno::RuntimeException)
160 {
161 Sequence< Reference< XParameter > > s1(_desc.getParameters());
162 Sequence< Reference< XMethodParameter > > s2(s1.getLength());
163 for (sal_Int32 i = 0; i < s1.getLength(); ++i) {
164 s2[i] = s1[i].get();
165 }
166 return s2;
167 }
168 //__________________________________________________________________________________________________
getExceptions()169 Sequence<Reference<XTypeDescription > > InterfaceMethodImpl::getExceptions()
170 throw(::com::sun::star::uno::RuntimeException)
171 {
172 Sequence< Reference< XCompoundTypeDescription > > s1(
173 _desc.getExceptions());
174 Sequence< Reference< XTypeDescription > > s2(s1.getLength());
175 for (sal_Int32 i = 0; i < s1.getLength(); ++i) {
176 s2[i] = s1[i].get();
177 }
178 return s2;
179 }
180
181
182 //##################################################################################################
183 //##################################################################################################
184 //##################################################################################################
185
186
187 //==================================================================================================
188 class InterfaceAttributeImpl : public WeakImplHelper1< XInterfaceAttributeTypeDescription2 >
189 {
190 Reference< XHierarchicalNameAccess > _xTDMgr;
191
192 OUString _aTypeName;
193 OUString _aMemberName;
194
195 OUString _aMemberTypeName;
196 Reference< XTypeDescription > _xMemberTD;
197
198 sal_Bool _bReadOnly;
199 sal_Bool _bBound;
200 sal_Int32 _nPosition;
201
202 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > _getter;
203 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > _setter;
204
205 public:
InterfaceAttributeImpl(const Reference<XHierarchicalNameAccess> & xTDMgr,const OUString & rTypeName,const OUString & rMemberName,const OUString & rMemberTypeName,sal_Bool bReadOnly,sal_Bool bBound,std::auto_ptr<stoc::registry_tdprovider::FunctionDescription> & getter,std::auto_ptr<stoc::registry_tdprovider::FunctionDescription> & setter,sal_Int32 nPosition)206 InterfaceAttributeImpl(
207 const Reference< XHierarchicalNameAccess > & xTDMgr,
208 const OUString & rTypeName,
209 const OUString & rMemberName,
210 const OUString & rMemberTypeName,
211 sal_Bool bReadOnly,
212 sal_Bool bBound,
213 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > &
214 getter,
215 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > &
216 setter,
217 sal_Int32 nPosition )
218 : _xTDMgr( xTDMgr )
219 , _aTypeName( rTypeName )
220 , _aMemberName( rMemberName )
221 , _aMemberTypeName( rMemberTypeName )
222 , _bReadOnly( bReadOnly )
223 , _bBound( bBound )
224 , _nPosition( nPosition )
225 , _getter( getter )
226 , _setter( setter )
227 {
228 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
229 }
230 virtual ~InterfaceAttributeImpl();
231
232 // XTypeDescription
233 virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
234 virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
235
236 // XInterfaceMemberTypeDescription
237 virtual OUString SAL_CALL getMemberName() throw(::com::sun::star::uno::RuntimeException);
238 virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException);
239
240 // XInterfaceAttributeTypeDescription2
241 virtual sal_Bool SAL_CALL isReadOnly() throw(::com::sun::star::uno::RuntimeException);
242 virtual Reference< XTypeDescription > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
243
isBound()244 virtual sal_Bool SAL_CALL isBound() throw (RuntimeException)
245 { return _bBound; }
246
247 virtual Sequence< Reference< XCompoundTypeDescription > > SAL_CALL
getGetExceptions()248 getGetExceptions() throw (RuntimeException)
249 {
250 if (_getter.get() != 0) {
251 return _getter->getExceptions();
252 } else {
253 return Sequence< Reference< XCompoundTypeDescription > >();
254 }
255 }
256
257 virtual Sequence< Reference< XCompoundTypeDescription > > SAL_CALL
getSetExceptions()258 getSetExceptions() throw (RuntimeException)
259 {
260 if (_setter.get() != 0) {
261 return _setter->getExceptions();
262 } else {
263 return Sequence< Reference< XCompoundTypeDescription > >();
264 }
265 }
266 };
267
~InterfaceAttributeImpl()268 InterfaceAttributeImpl::~InterfaceAttributeImpl()
269 {
270 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
271 }
272 // XTypeDescription
273 //__________________________________________________________________________________________________
getTypeClass()274 TypeClass InterfaceAttributeImpl::getTypeClass()
275 throw(::com::sun::star::uno::RuntimeException)
276 {
277 return TypeClass_INTERFACE_ATTRIBUTE;
278 }
279 //__________________________________________________________________________________________________
getName()280 OUString InterfaceAttributeImpl::getName()
281 throw(::com::sun::star::uno::RuntimeException)
282 {
283 return _aTypeName;
284 }
285
286 // XInterfaceMemberTypeDescription
287 //__________________________________________________________________________________________________
getMemberName()288 OUString InterfaceAttributeImpl::getMemberName()
289 throw(::com::sun::star::uno::RuntimeException)
290 {
291 return _aMemberName;
292 }
293 //__________________________________________________________________________________________________
getPosition()294 sal_Int32 InterfaceAttributeImpl::getPosition()
295 throw(::com::sun::star::uno::RuntimeException)
296 {
297 return _nPosition;
298 }
299
300 // XInterfaceAttributeTypeDescription2
301 //__________________________________________________________________________________________________
isReadOnly()302 sal_Bool InterfaceAttributeImpl::isReadOnly()
303 throw(::com::sun::star::uno::RuntimeException)
304 {
305 return _bReadOnly;
306 }
307 //__________________________________________________________________________________________________
getType()308 Reference<XTypeDescription > InterfaceAttributeImpl::getType()
309 throw(::com::sun::star::uno::RuntimeException)
310 {
311 if (!_xMemberTD.is() && _aMemberTypeName.getLength())
312 {
313 try
314 {
315 Reference< XTypeDescription > xMemberTD;
316 if (_xTDMgr->getByHierarchicalName( _aMemberTypeName ) >>= xMemberTD)
317 {
318 MutexGuard aGuard( getMutex() );
319 if (! _xMemberTD.is())
320 _xMemberTD = xMemberTD;
321 return _xMemberTD;
322 }
323 }
324 catch (NoSuchElementException &)
325 {
326 }
327 // never try again, if no td was found
328 _aMemberTypeName = OUString();
329 }
330 return _xMemberTD;
331 }
332
333
334 //##################################################################################################
335 //##################################################################################################
336 //##################################################################################################
337
checkInterfaceType(Reference<XTypeDescription> const & type)338 void InterfaceTypeDescriptionImpl::checkInterfaceType(
339 Reference< XTypeDescription > const & type)
340 {
341 if (resolveTypedefs(type)->getTypeClass() != TypeClass_INTERFACE) {
342 throw RuntimeException(
343 OUString(
344 RTL_CONSTASCII_USTRINGPARAM(
345 "Interface base is not an interface type")),
346 static_cast< OWeakObject * >(this));
347 }
348 }
349
350 namespace {
351
352 class BaseOffset {
353 public:
354 BaseOffset(Reference< XInterfaceTypeDescription2 > const & desc);
355
get() const356 sal_Int32 get() const { return offset; }
357
358 private:
359 void calculateBases(Reference< XInterfaceTypeDescription2 > const & desc);
360
361 void calculate(Reference< XInterfaceTypeDescription2 > const & desc);
362
363 std::set< rtl::OUString > set;
364 sal_Int32 offset;
365 };
366
BaseOffset(Reference<XInterfaceTypeDescription2> const & desc)367 BaseOffset::BaseOffset(Reference< XInterfaceTypeDescription2 > const & desc) {
368 offset = 0;
369 calculateBases(desc);
370 }
371
calculateBases(Reference<XInterfaceTypeDescription2> const & desc)372 void BaseOffset::calculateBases(
373 Reference< XInterfaceTypeDescription2 > const & desc)
374 {
375 Sequence< Reference < XTypeDescription > > bases(desc->getBaseTypes());
376 for (sal_Int32 i = 0; i < bases.getLength(); ++i) {
377 calculate(
378 Reference< XInterfaceTypeDescription2 >(
379 resolveTypedefs(bases[i]), UNO_QUERY_THROW));
380 }
381 }
382
calculate(Reference<XInterfaceTypeDescription2> const & desc)383 void BaseOffset::calculate(Reference< XInterfaceTypeDescription2 > const & desc)
384 {
385 if (set.insert(desc->getName()).second) {
386 calculateBases(desc);
387 offset += desc->getMembers().getLength();
388 }
389 }
390
391 }
392
393 //__________________________________________________________________________________________________
InterfaceTypeDescriptionImpl(const Reference<XHierarchicalNameAccess> & xTDMgr,const OUString & rName,const Sequence<OUString> & rBaseTypes,const Sequence<OUString> & rOptionalBaseTypes,const Sequence<sal_Int8> & rBytes,bool published)394 InterfaceTypeDescriptionImpl::InterfaceTypeDescriptionImpl(
395 const Reference< XHierarchicalNameAccess > & xTDMgr,
396 const OUString & rName, const Sequence< OUString > & rBaseTypes,
397 const Sequence< OUString > & rOptionalBaseTypes,
398 const Sequence< sal_Int8 > & rBytes, bool published )
399 : _xTDMgr( xTDMgr )
400 , _aBytes( rBytes )
401 , _aName( rName )
402 , _aBaseTypes( rBaseTypes )
403 , _aOptionalBaseTypes( rOptionalBaseTypes )
404 , _membersInit( false )
405 , _published( published )
406 {
407 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
408 }
409 //__________________________________________________________________________________________________
~InterfaceTypeDescriptionImpl()410 InterfaceTypeDescriptionImpl::~InterfaceTypeDescriptionImpl()
411 {
412 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
413 }
414
415 // XTypeDescription
416 //__________________________________________________________________________________________________
getTypeClass()417 TypeClass InterfaceTypeDescriptionImpl::getTypeClass()
418 throw(::com::sun::star::uno::RuntimeException)
419 {
420 return TypeClass_INTERFACE;
421 }
422 //__________________________________________________________________________________________________
getName()423 OUString InterfaceTypeDescriptionImpl::getName()
424 throw(::com::sun::star::uno::RuntimeException)
425 {
426 return _aName;
427 }
428
429 // XInterfaceTypeDescription2
430 //__________________________________________________________________________________________________
getBaseType()431 Reference< XTypeDescription > InterfaceTypeDescriptionImpl::getBaseType()
432 throw(::com::sun::star::uno::RuntimeException)
433 {
434 Sequence< Reference< XTypeDescription > > aBaseTypes(getBaseTypes());
435 return aBaseTypes.getLength() >= 1 ? aBaseTypes[0] : 0;
436 }
437 //__________________________________________________________________________________________________
getUik()438 Uik SAL_CALL InterfaceTypeDescriptionImpl::getUik()
439 throw(::com::sun::star::uno::RuntimeException)
440 {
441 return Uik();
442 }
443 //__________________________________________________________________________________________________
getMembers()444 Sequence< Reference< XInterfaceMemberTypeDescription > > InterfaceTypeDescriptionImpl::getMembers()
445 throw(::com::sun::star::uno::RuntimeException)
446 {
447 osl::MutexGuard guard(getMutex());
448 if (!_membersInit) {
449 _nBaseOffset = BaseOffset(this).get();
450 typereg::Reader reader(
451 _aBytes.getConstArray(), _aBytes.getLength(), false,
452 TYPEREG_VERSION_1);
453 sal_Int32 count = 0;
454 sal_uInt16 methodCount = reader.getMethodCount();
455 {for (sal_uInt16 i = 0; i < methodCount; ++i) {
456 RTMethodMode flags = reader.getMethodFlags(i);
457 if (flags != RT_MODE_ATTRIBUTE_GET
458 && flags != RT_MODE_ATTRIBUTE_SET)
459 {
460 ++count;
461 }
462 }}
463 sal_uInt16 fieldCount = reader.getFieldCount();
464 count += fieldCount;
465 _members.realloc(count);
466 sal_Int32 index = 0;
467 {for (sal_uInt16 i = 0; i < fieldCount; ++i) {
468 rtl::OUString name(reader.getFieldName(i));
469 rtl::OUStringBuffer typeName(getName());
470 typeName.appendAscii(RTL_CONSTASCII_STRINGPARAM("::"));
471 typeName.append(name);
472 RTFieldAccess flags = reader.getFieldFlags(i);
473 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription >
474 getter;
475 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription >
476 setter;
477 for (sal_uInt16 j = 0; j < methodCount; ++j) {
478 if (reader.getMethodName(j) == name) {
479 switch (reader.getMethodFlags(j)) {
480 case RT_MODE_ATTRIBUTE_GET:
481 OSL_ASSERT(getter.get() == 0);
482 getter.reset(
483 new stoc::registry_tdprovider::FunctionDescription(
484 _xTDMgr, _aBytes, j));
485 break;
486
487 case RT_MODE_ATTRIBUTE_SET:
488 OSL_ASSERT(setter.get() == 0);
489 setter.reset(
490 new stoc::registry_tdprovider::FunctionDescription(
491 _xTDMgr, _aBytes, j));
492 break;
493
494 default:
495 OSL_ASSERT(false);
496 break;
497 }
498 }
499 }
500 _members[index] = new InterfaceAttributeImpl(
501 _xTDMgr, typeName.makeStringAndClear(), name,
502 reader.getFieldTypeName(i).replace('/', '.'),
503 (flags & RT_ACCESS_READONLY) != 0,
504 (flags & RT_ACCESS_BOUND) != 0, getter, setter,
505 _nBaseOffset + index);
506 ++index;
507 }}
508 {for (sal_uInt16 i = 0; i < methodCount; ++i) {
509 RTMethodMode flags = reader.getMethodFlags(i);
510 if (flags != RT_MODE_ATTRIBUTE_GET
511 && flags != RT_MODE_ATTRIBUTE_SET)
512 {
513 rtl::OUString name(reader.getMethodName(i));
514 rtl::OUStringBuffer typeName(getName());
515 typeName.appendAscii(RTL_CONSTASCII_STRINGPARAM("::"));
516 typeName.append(name);
517 _members[index] = new InterfaceMethodImpl(
518 _xTDMgr, typeName.makeStringAndClear(), name,
519 reader.getMethodReturnTypeName(i).replace('/', '.'),
520 _aBytes, i, flags == RT_MODE_ONEWAY, _nBaseOffset + index);
521 ++index;
522 }
523 }}
524 _membersInit = true;
525 }
526 return _members;
527 }
528
529 Sequence< Reference< XTypeDescription > >
getBaseTypes()530 InterfaceTypeDescriptionImpl::getBaseTypes() throw (RuntimeException) {
531 MutexGuard guard(getMutex());
532 if (_xBaseTDs.getLength() == 0 && _aBaseTypes.getLength() != 0) {
533 Sequence< Reference< XTypeDescription > > tds(_aBaseTypes.getLength());
534 for (sal_Int32 i = 0; i < _aBaseTypes.getLength(); ++i) {
535 try {
536 _xTDMgr->getByHierarchicalName(_aBaseTypes[i]) >>= tds[i];
537 } catch (NoSuchElementException & e) {
538 throw RuntimeException(
539 (OUString(
540 RTL_CONSTASCII_USTRINGPARAM(
541 "com.sun.star.container.NoSuchElementException: "))
542 + e.Message),
543 static_cast< OWeakObject * >(this));
544 }
545 OSL_ASSERT(tds[i].is());
546 checkInterfaceType(tds[i]);
547 }
548 _xBaseTDs = tds;
549 }
550 return _xBaseTDs;
551 }
552
553 Sequence< Reference< XTypeDescription > >
getOptionalBaseTypes()554 InterfaceTypeDescriptionImpl::getOptionalBaseTypes() throw (RuntimeException) {
555 MutexGuard guard(getMutex());
556 if (_xOptionalBaseTDs.getLength() == 0
557 && _aOptionalBaseTypes.getLength() != 0)
558 {
559 Sequence< Reference< XTypeDescription > > tds(
560 _aOptionalBaseTypes.getLength());
561 for (sal_Int32 i = 0; i < _aOptionalBaseTypes.getLength(); ++i) {
562 try {
563 _xTDMgr->getByHierarchicalName(_aOptionalBaseTypes[i])
564 >>= tds[i];
565 } catch (NoSuchElementException & e) {
566 throw RuntimeException(
567 (OUString(
568 RTL_CONSTASCII_USTRINGPARAM(
569 "com.sun.star.container.NoSuchElementException: "))
570 + e.Message),
571 static_cast< OWeakObject * >(this));
572 }
573 OSL_ASSERT(tds[i].is());
574 checkInterfaceType(tds[i]);
575 }
576 _xOptionalBaseTDs = tds;
577 }
578 return _xOptionalBaseTDs;
579 }
580
581 }
582