xref: /trunk/main/stoc/source/registry_tdprovider/tdservice.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 <com/sun/star/beans/PropertyAttribute.hpp>
29 #include "com/sun/star/uno/RuntimeException.hpp"
30 
31 #include "registry/reader.hxx"
32 #include "registry/version.h"
33 #include "base.hxx"
34 #include "methoddescription.hxx"
35 
36 #include <memory>
37 
38 using namespace com::sun::star;
39 
40 namespace {
41 
42 class Constructor:
43     public cppu::WeakImplHelper1< XServiceConstructorDescription >
44 {
45 public:
Constructor(Reference<XHierarchicalNameAccess> const & manager,rtl::OUString const & name,Sequence<sal_Int8> const & bytes,sal_uInt16 index)46     Constructor(
47         Reference< XHierarchicalNameAccess > const & manager,
48         rtl::OUString const & name, Sequence< sal_Int8 > const & bytes,
49         sal_uInt16 index):
50         m_desc(manager, name, bytes, index) {}
51 
~Constructor()52     virtual ~Constructor() {}
53 
isDefaultConstructor()54     virtual sal_Bool SAL_CALL isDefaultConstructor()
55     { return m_desc.getName().getLength() == 0; }
56 
getName()57     virtual rtl::OUString SAL_CALL getName()
58     { return m_desc.getName(); }
59 
getParameters()60     virtual Sequence< Reference< XParameter > > SAL_CALL getParameters()
61     { return m_desc.getParameters(); }
62 
63     virtual Sequence< Reference<XCompoundTypeDescription > > SAL_CALL
getExceptions()64     getExceptions()
65     { return m_desc.getExceptions(); }
66 
67 private:
68     Constructor(Constructor &); // not implemented
69     void operator =(Constructor); // not implemented
70 
71     stoc::registry_tdprovider::MethodDescription m_desc;
72 };
73 
74 }
75 
76 namespace stoc_rdbtdp
77 {
78 
79 //==================================================================================================
80 //
81 // class PropertyTypeDescriptionImpl
82 //
83 //==================================================================================================
84 class PropertyTypeDescriptionImpl : public WeakImplHelper1< XPropertyTypeDescription >
85 {
86     OUString                      _aName;
87     Reference< XTypeDescription > _xTD;
88     sal_Int16                     _nFlags;
89 
90 public:
PropertyTypeDescriptionImpl(const OUString & rName,const Reference<XTypeDescription> & xTD,sal_Int16 nFlags)91     PropertyTypeDescriptionImpl( const OUString & rName,
92                                  const Reference< XTypeDescription > & xTD,
93                                  sal_Int16 nFlags )
94     : _aName( rName ), _xTD( xTD ), _nFlags( nFlags )
95     {
96         g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
97     }
98     virtual ~PropertyTypeDescriptionImpl();
99 
100     // XTypeDescription
101     virtual TypeClass SAL_CALL getTypeClass();
102     virtual OUString SAL_CALL getName();
103 
104     // XPropertyTypeDescription
105     virtual sal_Int16 SAL_CALL getPropertyFlags();
106     virtual Reference< XTypeDescription > SAL_CALL getPropertyTypeDescription();
107 };
108 
109 //__________________________________________________________________________________________________
110 // virtual
~PropertyTypeDescriptionImpl()111 PropertyTypeDescriptionImpl::~PropertyTypeDescriptionImpl()
112 {
113     g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
114 }
115 
116 // XTypeDescription
117 //__________________________________________________________________________________________________
118 // virtual
getTypeClass()119 TypeClass PropertyTypeDescriptionImpl::getTypeClass()
120 {
121     return TypeClass_PROPERTY;
122 }
123 //__________________________________________________________________________________________________
124 // virtual
getName()125 OUString PropertyTypeDescriptionImpl::getName()
126 {
127     return _aName;
128 }
129 
130 // XPropertyTypeDescription
131 //__________________________________________________________________________________________________
132 // virtual
getPropertyFlags()133 sal_Int16 SAL_CALL PropertyTypeDescriptionImpl::getPropertyFlags()
134 {
135     return _nFlags;
136 }
137 
138 //__________________________________________________________________________________________________
139 // virtual
140 Reference< XTypeDescription > SAL_CALL
getPropertyTypeDescription()141 PropertyTypeDescriptionImpl::getPropertyTypeDescription()
142 {
143     return _xTD;
144 }
145 
146 //==================================================================================================
147 //
148 // ServiceTypeDescriptionImpl implementation
149 //
150 //==================================================================================================
151 
152 //__________________________________________________________________________________________________
153 // virtual
~ServiceTypeDescriptionImpl()154 ServiceTypeDescriptionImpl::~ServiceTypeDescriptionImpl()
155 {
156     g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
157 }
158 
159 // XTypeDescription
160 //__________________________________________________________________________________________________
161 // virtual
getTypeClass()162 TypeClass ServiceTypeDescriptionImpl::getTypeClass()
163 {
164     return TypeClass_SERVICE;
165 }
166 //__________________________________________________________________________________________________
167 // virtual
getName()168 OUString ServiceTypeDescriptionImpl::getName()
169 {
170     return _aName;
171 }
172 
173 // XServiceTypeDescription
174 //__________________________________________________________________________________________________
175 // virtual
176 Sequence< Reference< XServiceTypeDescription > > SAL_CALL
getMandatoryServices()177 ServiceTypeDescriptionImpl::getMandatoryServices()
178 {
179     getReferences();
180     return _aMandatoryServices;
181 }
182 
183 //__________________________________________________________________________________________________
184 // virtual
185 Sequence< Reference< XServiceTypeDescription > > SAL_CALL
getOptionalServices()186 ServiceTypeDescriptionImpl::getOptionalServices()
187 {
188     getReferences();
189     return _aOptionalServices;
190 }
191 
192 //__________________________________________________________________________________________________
193 // virtual
194 Sequence< Reference< XInterfaceTypeDescription > > SAL_CALL
getMandatoryInterfaces()195 ServiceTypeDescriptionImpl::getMandatoryInterfaces()
196 {
197     getReferences();
198     return _aMandatoryInterfaces;
199 }
200 
201 //__________________________________________________________________________________________________
202 // virtual
203 Sequence< Reference< XInterfaceTypeDescription > > SAL_CALL
getOptionalInterfaces()204 ServiceTypeDescriptionImpl::getOptionalInterfaces()
205 {
206     getReferences();
207     return _aOptionalInterfaces;
208 }
209 
210 //__________________________________________________________________________________________________
211 // virtual
212 Sequence< Reference< XPropertyTypeDescription > > SAL_CALL
getProperties()213 ServiceTypeDescriptionImpl::getProperties()
214 {
215     {
216         MutexGuard guard(getMutex());
217         if (_pProps.get() != 0) {
218             return *_pProps;
219         }
220     }
221 
222     typereg::Reader aReader(
223         _aBytes.getConstArray(), _aBytes.getLength(), false, TYPEREG_VERSION_1);
224 
225     sal_uInt16 nFields = (sal_uInt16)aReader.getFieldCount();
226     std::auto_ptr< Sequence< Reference< XPropertyTypeDescription > > >
227         pTempProps(
228             new Sequence< Reference< XPropertyTypeDescription > >(nFields));
229     Reference< XPropertyTypeDescription > * pProps = pTempProps->getArray();
230 
231     while ( nFields-- )
232     {
233         // name
234         OUStringBuffer aName( _aName );
235         aName.appendAscii( "." );
236         aName.append( aReader.getFieldName( nFields ) );
237 
238         // type description
239         Reference< XTypeDescription > xTD;
240         try
241         {
242             _xTDMgr->getByHierarchicalName(
243                 aReader.getFieldTypeName( nFields ).replace( '/', '.' ) )
244                     >>= xTD;
245         }
246         catch ( NoSuchElementException const & )
247         {
248         }
249         OSL_ENSURE( xTD.is(), "### no type description for property!" );
250 
251         // flags
252         RTFieldAccess nFlags = aReader.getFieldFlags( nFields );
253 
254         sal_Int16 nAttribs = 0;
255         if ( nFlags & RT_ACCESS_READONLY )
256             nAttribs |= beans::PropertyAttribute::READONLY;
257         if ( nFlags & RT_ACCESS_OPTIONAL )
258             nAttribs |= beans::PropertyAttribute::OPTIONAL;
259         if ( nFlags & RT_ACCESS_MAYBEVOID )
260             nAttribs |= beans::PropertyAttribute::MAYBEVOID;
261         if ( nFlags & RT_ACCESS_BOUND )
262             nAttribs |= beans::PropertyAttribute::BOUND;
263         if ( nFlags & RT_ACCESS_CONSTRAINED )
264             nAttribs |= beans::PropertyAttribute::CONSTRAINED;
265         if ( nFlags & RT_ACCESS_TRANSIENT )
266             nAttribs |= beans::PropertyAttribute::TRANSIENT;
267         if ( nFlags & RT_ACCESS_MAYBEAMBIGUOUS )
268             nAttribs |= beans::PropertyAttribute::MAYBEAMBIGUOUS;
269         if ( nFlags & RT_ACCESS_MAYBEDEFAULT )
270             nAttribs |= beans::PropertyAttribute::MAYBEDEFAULT;
271         if ( nFlags & RT_ACCESS_REMOVEABLE )
272             nAttribs |= beans::PropertyAttribute::REMOVEABLE;
273 
274         OSL_ENSURE( !(nFlags & RT_ACCESS_PROPERTY),
275                     "### RT_ACCESS_PROPERTY is unexpected here!" );
276         OSL_ENSURE( !(nFlags & RT_ACCESS_ATTRIBUTE),
277                     "### RT_ACCESS_ATTRIBUTE is unexpected here!" );
278         OSL_ENSURE( !(nFlags & RT_ACCESS_CONST),
279                     "### RT_ACCESS_CONST is unexpected here!" );
280         // always set, unless RT_ACCESS_READONLY is set.
281         //OSL_ENSURE( !(nFlags & RT_ACCESS_READWRITE),
282         //            "### RT_ACCESS_READWRITE is unexpected here" );
283         OSL_ENSURE( !(nFlags & RT_ACCESS_DEFAULT),
284                     "### RT_ACCESS_DEAFAULT is unexpected here" );
285 
286         pProps[ nFields ]
287             = new PropertyTypeDescriptionImpl( aName.makeStringAndClear(),
288                                                xTD,
289                                                nAttribs );
290     }
291 
292     MutexGuard guard(getMutex());
293     if (_pProps.get() == 0) {
294         _pProps = pTempProps;
295     }
296     return *_pProps;
297 }
298 
isSingleInterfaceBased()299 sal_Bool ServiceTypeDescriptionImpl::isSingleInterfaceBased()
300 {
301     getReferences();
302     return _xInterfaceTD.is();
303 }
304 
getInterface()305 Reference< XTypeDescription > ServiceTypeDescriptionImpl::getInterface()
306 {
307     getReferences();
308     return _xInterfaceTD;
309 }
310 
311 Sequence< Reference< XServiceConstructorDescription > >
getConstructors()312 ServiceTypeDescriptionImpl::getConstructors() {
313     MutexGuard guard(getMutex());
314     if (_pCtors.get() == 0) {
315         typereg::Reader reader(
316             _aBytes.getConstArray(), _aBytes.getLength(), false,
317             TYPEREG_VERSION_1);
318         sal_uInt16 ctorCount = reader.getMethodCount();
319         std::auto_ptr< Sequence< Reference< XServiceConstructorDescription > > >
320             ctors(
321                 new Sequence< Reference< XServiceConstructorDescription > >(
322                     ctorCount));
323         for (sal_uInt16 i = 0; i < ctorCount; ++i) {
324             rtl::OUString name(reader.getMethodName(i));
325             if (reader.getMethodFlags(i) != RT_MODE_TWOWAY
326                 || (!reader.getMethodReturnTypeName(i).equalsAsciiL(
327                         RTL_CONSTASCII_STRINGPARAM("void")))
328                 || (name.getLength() == 0
329                     && (ctorCount != 1 || reader.getMethodParameterCount(i) != 0
330                         || reader.getMethodExceptionCount(i) != 0)))
331             {
332                 throw RuntimeException(
333                     rtl::OUString(
334                         RTL_CONSTASCII_USTRINGPARAM(
335                             "Service has bad constructors")),
336                     static_cast< OWeakObject * >(this));
337             }
338             (*ctors)[i] = new Constructor(
339                 _xTDMgr, reader.getMethodName(i), _aBytes, i);
340         }
341         _pCtors = ctors;
342     }
343     return *_pCtors;
344 }
345 
346 //__________________________________________________________________________________________________
getReferences()347 void ServiceTypeDescriptionImpl::getReferences()
348 {
349     {
350         MutexGuard guard(getMutex());
351         if (_bInitReferences) {
352             return;
353         }
354     }
355     typereg::Reader aReader(
356         _aBytes.getConstArray(), _aBytes.getLength(), false, TYPEREG_VERSION_1);
357     sal_uInt16 superTypes = aReader.getSuperTypeCount();
358     if (superTypes > 1) {
359         throw RuntimeException(
360             rtl::OUString(
361                 RTL_CONSTASCII_USTRINGPARAM(
362                     "Service has more than one supertype")),
363             static_cast< OWeakObject * >(this));
364     }
365     if (superTypes == 1) {
366         OUString aBaseName( aReader.getSuperTypeName(0).replace( '/', '.' ) );
367         if ( aReader.getReferenceCount() != 0
368              || aReader.getFieldCount() != 0 )
369             throw RuntimeException(
370                 OUString(
371                     RTL_CONSTASCII_USTRINGPARAM(
372                         "Service is single-interface--based but also has"
373                         " references and/or properties" ) ),
374                 static_cast< OWeakObject * >( this ) );
375         Reference< XTypeDescription > ifc;
376         try
377         {
378             _xTDMgr->getByHierarchicalName( aBaseName ) >>= ifc;
379         }
380         catch ( NoSuchElementException const & e )
381         {
382             throw RuntimeException(
383                 OUString(
384                     RTL_CONSTASCII_USTRINGPARAM(
385                         "com.sun.star.container.NoSuchElementException: " ) )
386                 + e.Message,
387                 static_cast< OWeakObject * >( this ) );
388         }
389         OSL_ASSERT(ifc.is());
390         if (resolveTypedefs(ifc)->getTypeClass() != TypeClass_INTERFACE) {
391             throw RuntimeException(
392                 OUString(
393                     RTL_CONSTASCII_USTRINGPARAM(
394                         "Single-interface--based service is not based on"
395                         " interface type" ) ),
396                 static_cast< OWeakObject * >( this ) );
397         }
398         MutexGuard guard(getMutex());
399         if (!_bInitReferences) {
400             _xInterfaceTD = ifc;
401             _bInitReferences = true;
402         }
403     }
404     else
405     {
406         sal_uInt16 nRefs = aReader.getReferenceCount();
407         Sequence< Reference< XServiceTypeDescription > > aMandatoryServices(
408             nRefs);
409         Sequence< Reference< XServiceTypeDescription > > aOptionalServices(
410             nRefs);
411         Sequence< Reference< XInterfaceTypeDescription > > aMandatoryInterfaces(
412             nRefs);
413         Sequence< Reference< XInterfaceTypeDescription > > aOptionalInterfaces(
414             nRefs);
415         sal_uInt32 nMS = 0;
416         sal_uInt32 nOS = 0;
417         sal_uInt32 nMI = 0;
418         sal_uInt32 nOI = 0;
419 
420         for ( sal_uInt16 nPos = 0; nPos < nRefs; ++nPos )
421         {
422             RTReferenceType eType = aReader.getReferenceSort( nPos );
423             switch ( eType )
424             {
425             case RT_REF_EXPORTS: // service
426                 {
427                     uno::Any aTypeDesc;
428                     try
429                     {
430                         aTypeDesc = _xTDMgr->getByHierarchicalName(
431                             aReader.getReferenceTypeName( nPos ).replace(
432                                 '/', '.' ) );
433                     }
434                     catch ( NoSuchElementException const & e )
435                     {
436                         throw RuntimeException(
437                             OUString(
438                                 RTL_CONSTASCII_USTRINGPARAM(
439                                     "com.sun.star.container."
440                                     "NoSuchElementException: " ) )
441                             + e.Message,
442                             static_cast< OWeakObject * >( this ) );
443                     }
444 
445                     RTFieldAccess nAccess = aReader.getReferenceFlags( nPos );
446                     if ( nAccess & RT_ACCESS_OPTIONAL )
447                     {
448                         // optional service
449                         if ( !( aTypeDesc >>= aOptionalServices[ nOS ] ) )
450                             throw RuntimeException(
451                                 OUString(
452                                     RTL_CONSTASCII_USTRINGPARAM(
453                                         "Service 'export' is not a service" ) ),
454                                 static_cast< OWeakObject * >( this ) );
455                         nOS++;
456                     }
457                     else
458                     {
459                         // mandatory service
460                         if ( !( aTypeDesc >>= aMandatoryServices[ nMS ] ) )
461                             throw RuntimeException(
462                                 OUString(
463                                     RTL_CONSTASCII_USTRINGPARAM(
464                                         "Service 'export' is not a service" ) ),
465                                 static_cast< OWeakObject * >( this ) );
466                         nMS++;
467                     }
468                     break;
469                 }
470             case RT_REF_SUPPORTS: // interface
471                 {
472                     uno::Any aTypeDesc;
473                     try
474                     {
475                         aTypeDesc = _xTDMgr->getByHierarchicalName(
476                             aReader.getReferenceTypeName( nPos ).replace(
477                                 '/', '.' ) );
478                     }
479                     catch ( NoSuchElementException const & e )
480                     {
481                         throw RuntimeException(
482                             OUString(
483                                 RTL_CONSTASCII_USTRINGPARAM(
484                                     "com.sun.star.container."
485                                     "NoSuchElementException: " ) )
486                             + e.Message,
487                             static_cast< OWeakObject * >( this ) );
488                     }
489 
490                     RTFieldAccess nAccess = aReader.getReferenceFlags( nPos );
491                     if ( nAccess & RT_ACCESS_OPTIONAL )
492                     {
493                         // optional interface
494                         if ( !( aTypeDesc >>= aOptionalInterfaces[ nOI ] ) )
495                             throw RuntimeException(
496                                 OUString(
497                                     RTL_CONSTASCII_USTRINGPARAM(
498                                         "Service 'supports' is not an"
499                                         " interface" ) ),
500                                 static_cast< OWeakObject * >( this ) );
501                         nOI++;
502                     }
503                     else
504                     {
505                         // mandatory interface
506                         if ( !( aTypeDesc >>= aMandatoryInterfaces[ nMI ] ) )
507                             throw RuntimeException(
508                                 OUString(
509                                     RTL_CONSTASCII_USTRINGPARAM(
510                                         "Service 'supports' is not an"
511                                         " interface" ) ),
512                                 static_cast< OWeakObject * >( this ) );
513                         nMI++;
514                     }
515                     break;
516                 }
517             case RT_REF_OBSERVES:
518             case RT_REF_NEEDS:
519                 break;
520             default:
521                 OSL_ENSURE( sal_False, "### unsupported reference type!" );
522                 break;
523             }
524         }
525         aMandatoryServices.realloc( nMS );
526         aOptionalServices.realloc( nOS );
527         aMandatoryInterfaces.realloc( nMI );
528         aOptionalInterfaces.realloc( nOI );
529 
530         MutexGuard guard(getMutex());
531         if (!_bInitReferences) {
532             _aMandatoryServices = aMandatoryServices;
533             _aOptionalServices = aOptionalServices;
534             _aMandatoryInterfaces = aMandatoryInterfaces;
535             _aOptionalInterfaces = aOptionalInterfaces;
536             _bInitReferences = true;
537         }
538     }
539 }
540 
541 
542 }
543