xref: /trunk/main/stoc/source/registry_tdprovider/tdiface.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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