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