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