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