Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <sal/config.h>
21 :
22 : #include <cassert>
23 : #include <cstddef>
24 : #include <limits>
25 : #include <map>
26 : #include <set>
27 :
28 : #include <osl/diagnose.h>
29 : #include <osl/mutex.hxx>
30 : #include <osl/thread.h>
31 : #include <cppuhelper/basemutex.hxx>
32 : #include <cppuhelper/compbase2.hxx>
33 : #include <cppuhelper/queryinterface.hxx>
34 : #include <cppuhelper/weak.hxx>
35 : #include <cppuhelper/component.hxx>
36 : #include <cppuhelper/factory.hxx>
37 : #include <cppuhelper/implbase3.hxx>
38 : #include <cppuhelper/supportsservice.hxx>
39 : #include <cppuhelper/typeprovider.hxx>
40 : #include <salhelper/simplereferenceobject.hxx>
41 :
42 : #include <com/sun/star/uno/DeploymentException.hpp>
43 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
44 : #include <com/sun/star/lang/XServiceInfo.hpp>
45 : #include <com/sun/star/lang/XEventListener.hpp>
46 : #include <com/sun/star/reflection/XIdlReflection.hpp>
47 : #include <com/sun/star/reflection/XIdlClass.hpp>
48 : #include <com/sun/star/reflection/XIdlField2.hpp>
49 : #include <com/sun/star/reflection/theCoreReflection.hpp>
50 : #include <com/sun/star/beans/UnknownPropertyException.hpp>
51 : #include <com/sun/star/beans/Property.hpp>
52 : #include <com/sun/star/beans/XPropertySet.hpp>
53 : #include <com/sun/star/beans/XFastPropertySet.hpp>
54 : #include <com/sun/star/beans/XIntrospection.hpp>
55 : #include <com/sun/star/beans/XIntrospectionAccess.hpp>
56 : #include <com/sun/star/beans/XMaterialHolder.hpp>
57 : #include <com/sun/star/beans/XExactName.hpp>
58 : #include <com/sun/star/beans/PropertyAttribute.hpp>
59 : #include <com/sun/star/beans/PropertyConcept.hpp>
60 : #include <com/sun/star/beans/MethodConcept.hpp>
61 : #include <com/sun/star/container/XNameContainer.hpp>
62 : #include <com/sun/star/container/XIndexContainer.hpp>
63 : #include <com/sun/star/container/XEnumerationAccess.hpp>
64 :
65 : #include <rtl/ref.hxx>
66 : #include <rtl/ustrbuf.hxx>
67 : #include <rtl/strbuf.hxx>
68 : #include <boost/unordered_map.hpp>
69 :
70 : using namespace css::uno;
71 : using namespace css::lang;
72 : using namespace css::reflection;
73 : using namespace css::container;
74 : using namespace css::registry;
75 : using namespace css::beans;
76 : using namespace css::beans::PropertyAttribute;
77 : using namespace css::beans::PropertyConcept;
78 : using namespace css::beans::MethodConcept;
79 : using namespace cppu;
80 : using namespace osl;
81 :
82 : namespace
83 : {
84 :
85 : typedef WeakImplHelper3< XIntrospectionAccess, XMaterialHolder, XExactName > IntrospectionAccessHelper;
86 :
87 :
88 :
89 :
90 : // Special value for Method-Concept, to be able to mark "normal" functions
91 : #define MethodConcept_NORMAL_IMPL 0x80000000
92 :
93 :
94 : // Method to assert, if a class is derived from another class
95 5356 : bool isDerivedFrom( Reference<XIdlClass> xToTestClass, Reference<XIdlClass> xDerivedFromClass )
96 : {
97 5356 : Sequence< Reference<XIdlClass> > aClassesSeq = xToTestClass->getSuperclasses();
98 5356 : const Reference<XIdlClass>* pClassesArray = aClassesSeq.getConstArray();
99 :
100 5356 : sal_Int32 nSuperClassCount = aClassesSeq.getLength();
101 5358 : for ( sal_Int32 i = 0; i < nSuperClassCount; ++i )
102 : {
103 4178 : const Reference<XIdlClass>& rxClass = pClassesArray[i];
104 :
105 12538 : if ( xDerivedFromClass->equals( rxClass ) ||
106 4186 : isDerivedFrom( rxClass, xDerivedFromClass )
107 : )
108 4176 : return true;
109 : }
110 :
111 1180 : return false;
112 : }
113 :
114 :
115 :
116 : // *** Classification of Properties (no enum, to be able to use Sequence) ***
117 : // Properties from a PropertySet-Interface
118 : #define MAP_PROPERTY_SET 0
119 : // Properties from Fields
120 : #define MAP_FIELD 1
121 : // Properties, that get described with get/set-Methods
122 : #define MAP_GETSET 2
123 : // Properties, with only a set-Method
124 : #define MAP_SETONLY 3
125 :
126 :
127 : // Increments, in which the size of Sequences get adjusted
128 : #define ARRAY_SIZE_STEP 20
129 :
130 :
131 :
132 :
133 : //*** IntrospectionAccessStatic_Impl ***
134 :
135 : // Equals to the old IntrospectionAccessImpl, forms now a static
136 : // part of the new Instance-related ImplIntrospectionAccess
137 :
138 : // Hashtable for the search of names
139 : typedef boost::unordered_map
140 : <
141 : OUString,
142 : sal_Int32,
143 : OUStringHash
144 : >
145 : IntrospectionNameMap;
146 :
147 :
148 : // Hashtable to assign exact names to the Lower-Case
149 : // converted names, for the support of XExactName
150 : typedef boost::unordered_map
151 : <
152 : OUString,
153 : OUString,
154 : OUStringHash
155 : >
156 : LowerToExactNameMap;
157 :
158 :
159 : class ImplIntrospectionAccess;
160 : class IntrospectionAccessStatic_Impl: public salhelper::SimpleReferenceObject
161 : {
162 : friend class Implementation;
163 : friend class ImplIntrospectionAccess;
164 :
165 : // Holding CoreReflection
166 : Reference< XIdlReflection > mxCoreReflection;
167 :
168 : // InterfaceSequences, to save additional information in a property
169 : // for example the Field at MAP_FIELD, the get/set-Methods at MAP_GETSET, et cetera
170 : Sequence< Reference<XInterface> > aInterfaceSeq1;
171 : Sequence< Reference<XInterface> > aInterfaceSeq2;
172 :
173 : // Hashtables for names
174 : IntrospectionNameMap maPropertyNameMap;
175 : IntrospectionNameMap maMethodNameMap;
176 : LowerToExactNameMap maLowerToExactNameMap;
177 :
178 : // Sequence of all Properties, also for delivering from getProperties()
179 : Sequence<Property> maAllPropertySeq;
180 :
181 : // Mapping of properties to Access-Types
182 : Sequence<sal_Int16> maMapTypeSeq;
183 :
184 : // Classification of found methods
185 : Sequence<sal_Int32> maPropertyConceptSeq;
186 :
187 : // Number of Properties
188 : sal_Int32 mnPropCount;
189 :
190 : // Number of Properties, which are assigned to particular concepts
191 : //sal_Int32 mnDangerousPropCount;
192 : sal_Int32 mnPropertySetPropCount;
193 : sal_Int32 mnAttributePropCount;
194 : sal_Int32 mnMethodPropCount;
195 :
196 : // Flag, if a FastPropertySet is supported
197 : bool mbFastPropSet;
198 :
199 : // Original-Handles of FastPropertySets
200 : sal_Int32* mpOrgPropertyHandleArray;
201 :
202 : // MethodSequence, that accepts all methods
203 : Sequence< Reference<XIdlMethod> > maAllMethodSeq;
204 :
205 : // Classification of found methods
206 : Sequence<sal_Int32> maMethodConceptSeq;
207 :
208 : // Number of methods
209 : sal_Int32 mnMethCount;
210 :
211 : // Sequence of Listener, that can be registered
212 : Sequence< Type > maSupportedListenerSeq;
213 :
214 : // Helper-methods for adjusting sizes of Sequences
215 : void checkPropertyArraysSize
216 : (
217 : Property*& rpAllPropArray,
218 : sal_Int16*& rpMapTypeArray,
219 : sal_Int32*& rpPropertyConceptArray,
220 : sal_Int32 iNextIndex
221 : );
222 : void checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq, Reference<XInterface>*& rpInterfaceArray,
223 : sal_Int32 iNextIndex );
224 :
225 : public:
226 : IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ );
227 1456 : virtual ~IntrospectionAccessStatic_Impl()
228 1456 : {
229 728 : delete[] mpOrgPropertyHandleArray;
230 1456 : }
231 : sal_Int32 getPropertyIndex( const OUString& aPropertyName ) const;
232 : sal_Int32 getMethodIndex( const OUString& aMethodName ) const;
233 :
234 : // Methods of XIntrospectionAccess (OLD, now only Impl)
235 : void setPropertyValue(const Any& obj, const OUString& aPropertyName, const Any& aValue) const;
236 : // void setPropertyValue(Any& obj, const OUString& aPropertyName, const Any& aValue) const;
237 : Any getPropertyValue(const Any& obj, const OUString& aPropertyName) const;
238 : void setPropertyValueByIndex(const Any& obj, sal_Int32 nIndex, const Any& aValue) const;
239 : // void setPropertyValueByIndex(Any& obj, sal_Int32 nIndex, const Any& aValue) const;
240 : Any getPropertyValueByIndex(const Any& obj, sal_Int32 nIndex) const;
241 :
242 2660 : Sequence<Property> getProperties(void) const { return maAllPropertySeq; }
243 3232 : Sequence< Reference<XIdlMethod> > getMethods(void) const { return maAllMethodSeq; }
244 18 : Sequence< Type > getSupportedListeners(void) const { return maSupportedListenerSeq; }
245 7138 : Sequence<sal_Int32> getPropertyConcepts(void) const { return maPropertyConceptSeq; }
246 5966 : Sequence<sal_Int32> getMethodConcepts(void) const { return maMethodConceptSeq; }
247 : };
248 :
249 :
250 : // Ctor
251 896 : IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ )
252 896 : : mxCoreReflection( xCoreReflection_ )
253 : {
254 896 : aInterfaceSeq1.realloc( ARRAY_SIZE_STEP );
255 896 : aInterfaceSeq2.realloc( ARRAY_SIZE_STEP );
256 :
257 : // Property-Data
258 896 : maAllPropertySeq.realloc( ARRAY_SIZE_STEP );
259 896 : maMapTypeSeq.realloc( ARRAY_SIZE_STEP );
260 896 : maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP );
261 :
262 896 : mbFastPropSet = false;
263 896 : mpOrgPropertyHandleArray = NULL;
264 :
265 896 : mnPropCount = 0;
266 : //mnDangerousPropCount = 0;
267 896 : mnPropertySetPropCount = 0;
268 896 : mnAttributePropCount = 0;
269 896 : mnMethodPropCount = 0;
270 :
271 : // Method-Data
272 896 : mnMethCount = 0;
273 896 : }
274 :
275 14748 : sal_Int32 IntrospectionAccessStatic_Impl::getPropertyIndex( const OUString& aPropertyName ) const
276 : {
277 14748 : sal_Int32 iHashResult = -1;
278 14748 : IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
279 14748 : IntrospectionNameMap::iterator aIt = pThis->maPropertyNameMap.find( aPropertyName );
280 14748 : if( !( aIt == pThis->maPropertyNameMap.end() ) )
281 12304 : iHashResult = (*aIt).second;
282 14748 : return iHashResult;
283 : }
284 :
285 6808 : sal_Int32 IntrospectionAccessStatic_Impl::getMethodIndex( const OUString& aMethodName ) const
286 : {
287 6808 : sal_Int32 iHashResult = -1;
288 6808 : IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
289 6808 : IntrospectionNameMap::iterator aIt = pThis->maMethodNameMap.find( aMethodName );
290 6808 : if( !( aIt == pThis->maMethodNameMap.end() ) )
291 : {
292 5576 : iHashResult = (*aIt).second;
293 : }
294 : // #95159 Check if full qualified name matches
295 : else
296 : {
297 1232 : sal_Int32 nSearchFrom = aMethodName.getLength();
298 : while( true )
299 : {
300 : // Strategy: Search back until the first '_' is found
301 1240 : sal_Int32 nFound = aMethodName.lastIndexOf( '_', nSearchFrom );
302 1240 : if( nFound == -1 )
303 2464 : break;
304 :
305 8 : OUString aPureMethodName = aMethodName.copy( nFound + 1 );
306 :
307 8 : aIt = pThis->maMethodNameMap.find( aPureMethodName );
308 8 : if( !( aIt == pThis->maMethodNameMap.end() ) )
309 : {
310 : // Check if it can be a type?
311 : // Problem: Does not work if package names contain _ ?!
312 0 : OUString aStr = aMethodName.copy( 0, nFound );
313 0 : OUString aTypeName = aStr.replace( '_', '.' );
314 0 : Reference< XIdlClass > xClass = mxCoreReflection->forName( aTypeName );
315 0 : if( xClass.is() )
316 : {
317 : // If this is a valid class it could be the right method
318 :
319 : // Could be the right method, type has to be checked
320 0 : iHashResult = (*aIt).second;
321 :
322 0 : const Reference<XIdlMethod>* pMethods = maAllMethodSeq.getConstArray();
323 0 : const Reference<XIdlMethod> xMethod = pMethods[ iHashResult ];
324 :
325 0 : Reference< XIdlClass > xMethClass = xMethod->getDeclaringClass();
326 0 : if( xClass->equals( xMethClass ) )
327 : {
328 0 : break;
329 : }
330 : else
331 : {
332 0 : iHashResult = -1;
333 :
334 : // Could also be another method with the same name
335 : // Iterate over all methods
336 0 : sal_Int32 nLen = maAllMethodSeq.getLength();
337 0 : for( int i = 0 ; i < nLen ; ++i )
338 : {
339 0 : const Reference<XIdlMethod> xMethod2 = pMethods[ i ];
340 0 : if( xMethod2->getName() == aPureMethodName )
341 : {
342 0 : Reference< XIdlClass > xMethClass2 = xMethod2->getDeclaringClass();
343 :
344 0 : if( xClass->equals( xMethClass2 ) )
345 : {
346 0 : iHashResult = i;
347 0 : break;
348 0 : }
349 : }
350 0 : }
351 :
352 0 : if( iHashResult != -1 )
353 0 : break;
354 0 : }
355 0 : }
356 : }
357 :
358 8 : nSearchFrom = nFound - 1;
359 8 : if( nSearchFrom < 0 )
360 0 : break;
361 8 : }
362 : }
363 6808 : return iHashResult;
364 : }
365 :
366 1258 : void IntrospectionAccessStatic_Impl::setPropertyValue( const Any& obj, const OUString& aPropertyName, const Any& aValue ) const
367 : //void IntrospectionAccessStatic_Impl::setPropertyValue( Any& obj, const OUString& aPropertyName, const Any& aValue ) const
368 : {
369 1258 : sal_Int32 i = getPropertyIndex( aPropertyName );
370 1258 : if( i != -1 )
371 1258 : setPropertyValueByIndex( obj, (sal_Int32)i, aValue );
372 : else
373 0 : throw UnknownPropertyException();
374 1258 : }
375 :
376 1258 : void IntrospectionAccessStatic_Impl::setPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
377 : //void IntrospectionAccessStatic_Impl::setPropertyValueByIndex( Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
378 : {
379 : // Is the passed object something that fits?
380 1258 : TypeClass eObjType = obj.getValueType().getTypeClass();
381 :
382 1258 : Reference<XInterface> xInterface;
383 1258 : if( eObjType == TypeClass_INTERFACE )
384 : {
385 1012 : xInterface = *( Reference<XInterface>*)obj.getValue();
386 : }
387 246 : else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
388 : {
389 0 : throw IllegalArgumentException();
390 : }
391 :
392 : // Test flags
393 1258 : const Property* pProps = maAllPropertySeq.getConstArray();
394 1258 : if( (pProps[ nSequenceIndex ].Attributes & READONLY) != 0 )
395 : {
396 0 : throw UnknownPropertyException();
397 : }
398 :
399 1258 : const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
400 1258 : switch( pMapTypeArray[ nSequenceIndex ] )
401 : {
402 : case MAP_PROPERTY_SET:
403 : {
404 : // Get Property
405 6 : const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
406 :
407 : // Convert Interface-Parameter to the correct type
408 6 : bool bUseCopy = false;
409 6 : Any aRealValue;
410 :
411 6 : TypeClass eValType = aValue.getValueType().getTypeClass();
412 6 : if( eValType == TypeClass_INTERFACE )
413 : {
414 2 : Type aPropType = rProp.Type;
415 4 : OUString aTypeName( aPropType.getTypeName() );
416 4 : Reference< XIdlClass > xPropClass = mxCoreReflection->forName( aTypeName );
417 : //Reference<XIdlClass> xPropClass = rProp.Type;
418 2 : if( xPropClass.is() && xPropClass->getTypeClass() == TypeClass_INTERFACE )
419 : {
420 2 : Reference<XInterface> valInterface = *(Reference<XInterface>*)aValue.getValue();
421 2 : if( valInterface.is() )
422 : {
423 : //Any queryInterface( const Type& rType );
424 2 : aRealValue = valInterface->queryInterface( aPropType );
425 2 : if( aRealValue.hasValue() )
426 2 : bUseCopy = true;
427 2 : }
428 2 : }
429 : }
430 :
431 : // Do we have a FastPropertySet and a valid Handle?
432 : // CAUTION: At this point we exploit, that the PropertySet
433 : // gets queried at the beginning of the Introspection-Process.
434 : sal_Int32 nOrgHandle;
435 6 : if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
436 : {
437 : // Retrieve PropertySet-Interface
438 : Reference<XFastPropertySet> xFastPropSet =
439 6 : Reference<XFastPropertySet>::query( xInterface );
440 6 : if( xFastPropSet.is() )
441 : {
442 6 : xFastPropSet->setFastPropertyValue( nOrgHandle, bUseCopy ? aRealValue : aValue );
443 : }
444 : else
445 : {
446 : // throw UnknownPropertyException
447 6 : }
448 : }
449 : // else take the normal one
450 : else
451 : {
452 : // Retrieve PropertySet-Interface
453 : Reference<XPropertySet> xPropSet =
454 0 : Reference<XPropertySet>::query( xInterface );
455 0 : if( xPropSet.is() )
456 : {
457 0 : xPropSet->setPropertyValue( rProp.Name, bUseCopy ? aRealValue : aValue );
458 : }
459 : else
460 : {
461 : // throw UnknownPropertyException
462 0 : }
463 6 : }
464 : }
465 6 : break;
466 :
467 : case MAP_FIELD:
468 : {
469 1174 : Reference<XIdlField> xField = static_cast<XIdlField*>(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
470 2348 : Reference<XIdlField2> xField2(xField, UNO_QUERY);
471 1174 : if( xField2.is() )
472 : {
473 1174 : xField2->set( (Any&)obj, aValue );
474 : // IllegalArgumentException
475 : // NullPointerException
476 : } else
477 0 : if( xField.is() )
478 : {
479 0 : xField->set( obj, aValue );
480 : // IllegalArgumentException
481 : // NullPointerException
482 : }
483 : else
484 : {
485 : // throw IllegalArgumentException();
486 1174 : }
487 : }
488 1174 : break;
489 :
490 : case MAP_GETSET:
491 : case MAP_SETONLY:
492 : {
493 : // Retrieve set-Methods
494 78 : Reference<XIdlMethod> xMethod = static_cast<XIdlMethod*>(aInterfaceSeq2.getConstArray()[ nSequenceIndex ].get());
495 78 : if( xMethod.is() )
496 : {
497 78 : Sequence<Any> args( 1 );
498 78 : args.getArray()[0] = aValue;
499 78 : xMethod->invoke( obj, args );
500 : }
501 : else
502 : {
503 : // throw IllegalArgumentException();
504 78 : }
505 : }
506 78 : break;
507 1258 : }
508 1258 : }
509 :
510 3908 : Any IntrospectionAccessStatic_Impl::getPropertyValue( const Any& obj, const OUString& aPropertyName ) const
511 : {
512 3908 : sal_Int32 i = getPropertyIndex( aPropertyName );
513 3908 : if( i != -1 )
514 7816 : return getPropertyValueByIndex( obj, i );
515 :
516 0 : throw UnknownPropertyException();
517 : }
518 :
519 3908 : Any IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex) const
520 : {
521 3908 : Any aRet;
522 :
523 : // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes?
524 3908 : TypeClass eObjType = obj.getValueType().getTypeClass();
525 :
526 7816 : Reference<XInterface> xInterface;
527 3908 : if( eObjType == TypeClass_INTERFACE )
528 : {
529 3032 : xInterface = *(Reference<XInterface>*)obj.getValue();
530 : }
531 876 : else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
532 : {
533 : // throw IllegalArgumentException();
534 0 : return aRet;
535 : }
536 :
537 3908 : const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
538 3908 : switch( pMapTypeArray[ nSequenceIndex ] )
539 : {
540 : case MAP_PROPERTY_SET:
541 : {
542 : // Property besorgen
543 6 : const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
544 :
545 : // Haben wir ein FastPropertySet und ein gueltiges Handle?
546 : // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet
547 : // zu Beginn des Introspection-Vorgangs abgefragt wird.
548 : sal_Int32 nOrgHandle;
549 6 : if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
550 : {
551 : // PropertySet-Interface holen
552 : Reference<XFastPropertySet> xFastPropSet =
553 6 : Reference<XFastPropertySet>::query( xInterface );
554 6 : if( xFastPropSet.is() )
555 : {
556 6 : aRet = xFastPropSet->getFastPropertyValue( nOrgHandle);
557 : }
558 : else
559 : {
560 : // throw UnknownPropertyException
561 0 : return aRet;
562 6 : }
563 : }
564 : // sonst eben das normale nehmen
565 : else
566 : {
567 : // PropertySet-Interface holen
568 : Reference<XPropertySet> xPropSet =
569 0 : Reference<XPropertySet>::query( xInterface );
570 0 : if( xPropSet.is() )
571 : {
572 0 : aRet = xPropSet->getPropertyValue( rProp.Name );
573 : }
574 : else
575 : {
576 : // throw UnknownPropertyException
577 0 : return aRet;
578 0 : }
579 : }
580 : }
581 6 : break;
582 :
583 : case MAP_FIELD:
584 : {
585 3396 : Reference<XIdlField> xField = static_cast<XIdlField*>(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
586 3396 : if( xField.is() )
587 : {
588 3396 : aRet = xField->get( obj );
589 : // IllegalArgumentException
590 : // NullPointerException
591 : }
592 : else
593 : {
594 : // throw IllegalArgumentException();
595 0 : return aRet;
596 3396 : }
597 : }
598 3396 : break;
599 :
600 : case MAP_GETSET:
601 : {
602 : // get-Methode holen
603 506 : Reference<XIdlMethod> xMethod = static_cast<XIdlMethod*>(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
604 506 : if( xMethod.is() )
605 : {
606 506 : Sequence<Any> args;
607 506 : aRet = xMethod->invoke( obj, args );
608 : }
609 : else
610 : {
611 : // throw IllegalArgumentException();
612 0 : return aRet;
613 506 : }
614 : }
615 506 : break;
616 :
617 : case MAP_SETONLY:
618 : // get-Methode gibt es nicht
619 : // throw WriteOnlyPropertyException();
620 0 : return aRet;
621 : }
622 3908 : return aRet;
623 : }
624 :
625 :
626 : // Hilfs-Methoden zur Groessen-Anpassung der Sequences
627 42952 : void IntrospectionAccessStatic_Impl::checkPropertyArraysSize
628 : (
629 : Property*& rpAllPropArray,
630 : sal_Int16*& rpMapTypeArray,
631 : sal_Int32*& rpPropertyConceptArray,
632 : sal_Int32 iNextIndex
633 : )
634 : {
635 42952 : sal_Int32 nLen = maAllPropertySeq.getLength();
636 42952 : if( iNextIndex >= nLen )
637 : {
638 1666 : maAllPropertySeq.realloc( nLen + ARRAY_SIZE_STEP );
639 1666 : rpAllPropArray = maAllPropertySeq.getArray();
640 :
641 1666 : maMapTypeSeq.realloc( nLen + ARRAY_SIZE_STEP );
642 1666 : rpMapTypeArray = maMapTypeSeq.getArray();
643 :
644 1666 : maPropertyConceptSeq.realloc( nLen + ARRAY_SIZE_STEP );
645 1666 : rpPropertyConceptArray = maPropertyConceptSeq.getArray();
646 : }
647 42952 : }
648 :
649 22254 : void IntrospectionAccessStatic_Impl::checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq,
650 : Reference<XInterface>*& rpInterfaceArray, sal_Int32 iNextIndex )
651 : {
652 22254 : sal_Int32 nLen = rSeq.getLength();
653 22254 : if( iNextIndex >= nLen )
654 : {
655 : // Neue Groesse mit ARRAY_SIZE_STEP abgleichen
656 2152 : sal_Int32 nMissingSize = iNextIndex - nLen + 1;
657 2152 : sal_Int32 nSteps = nMissingSize / ARRAY_SIZE_STEP + 1;
658 2152 : sal_Int32 nNewSize = nLen + nSteps * ARRAY_SIZE_STEP;
659 :
660 2152 : rSeq.realloc( nNewSize );
661 2152 : rpInterfaceArray = rSeq.getArray();
662 : }
663 22254 : }
664 :
665 :
666 :
667 : //*** ImplIntrospectionAccess ***
668 :
669 :
670 : // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
671 : // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
672 : // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
673 : class ImplIntrospectionAccess : public IntrospectionAccessHelper
674 : {
675 : friend class Implementation;
676 :
677 : // Untersuchtes Objekt
678 : Any maInspectedObject;
679 :
680 : // Als Interface
681 : Reference<XInterface> mxIface;
682 :
683 : // Statische Daten der Introspection
684 : rtl::Reference< IntrospectionAccessStatic_Impl > mpStaticImpl;
685 :
686 : // Adapter-Implementation
687 : WeakReference< XInterface > maAdapter;
688 :
689 : // Letzte Sequence, die bei getProperties geliefert wurde (Optimierung)
690 : Sequence<Property> maLastPropertySeq;
691 : sal_Int32 mnLastPropertyConcept;
692 :
693 : // Letzte Sequence, die bei getMethods geliefert wurde (Optimierung)
694 : Sequence<Reference<XIdlMethod> > maLastMethodSeq;
695 : sal_Int32 mnLastMethodConcept;
696 :
697 : public:
698 : ImplIntrospectionAccess( const Any& obj, rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ );
699 : virtual ~ImplIntrospectionAccess();
700 :
701 : // Methoden von XIntrospectionAccess
702 : virtual sal_Int32 SAL_CALL getSuppliedMethodConcepts(void)
703 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
704 : virtual sal_Int32 SAL_CALL getSuppliedPropertyConcepts(void)
705 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
706 : virtual Property SAL_CALL getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
707 : throw( NoSuchElementException, RuntimeException, std::exception ) SAL_OVERRIDE;
708 : virtual sal_Bool SAL_CALL hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
709 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
710 : virtual Sequence< Property > SAL_CALL getProperties(sal_Int32 PropertyConcepts)
711 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
712 : virtual Reference<XIdlMethod> SAL_CALL getMethod(const OUString& Name, sal_Int32 MethodConcepts)
713 : throw( NoSuchMethodException, RuntimeException, std::exception ) SAL_OVERRIDE;
714 : virtual sal_Bool SAL_CALL hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
715 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
716 : virtual Sequence< Reference<XIdlMethod> > SAL_CALL getMethods(sal_Int32 MethodConcepts)
717 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
718 : virtual Sequence< Type > SAL_CALL getSupportedListeners(void)
719 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
720 : using OWeakObject::queryAdapter;
721 : virtual Reference<XInterface> SAL_CALL queryAdapter( const Type& rType )
722 : throw( IllegalTypeException, RuntimeException, std::exception ) SAL_OVERRIDE;
723 :
724 : // Methoden von XMaterialHolder
725 : virtual Any SAL_CALL getMaterial(void) throw(RuntimeException, std::exception) SAL_OVERRIDE;
726 :
727 : // Methoden von XExactName
728 : virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
729 : };
730 :
731 16928 : ImplIntrospectionAccess::ImplIntrospectionAccess
732 : ( const Any& obj, rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ )
733 16928 : : maInspectedObject( obj ), mpStaticImpl( pStaticImpl_ ), maAdapter()
734 : {
735 : // Objekt als Interface merken, wenn moeglich
736 16928 : TypeClass eType = maInspectedObject.getValueType().getTypeClass();
737 16928 : if( eType == TypeClass_INTERFACE )
738 15786 : mxIface = *(Reference<XInterface>*)maInspectedObject.getValue();
739 :
740 16928 : mnLastPropertyConcept = -1;
741 16928 : mnLastMethodConcept = -1;
742 16928 : }
743 :
744 33600 : ImplIntrospectionAccess::~ImplIntrospectionAccess()
745 : {
746 33600 : }
747 :
748 :
749 :
750 : //*** ImplIntrospectionAdapter ***
751 :
752 :
753 : // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
754 : // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
755 : // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
756 21696 : class ImplIntrospectionAdapter :
757 : public XPropertySet, public XFastPropertySet, public XPropertySetInfo,
758 : public XNameContainer, public XIndexContainer,
759 : public XEnumerationAccess, public XIdlArray,
760 : public OWeakObject
761 : {
762 : // Parent-Objekt
763 : ::rtl::Reference< ImplIntrospectionAccess > mpAccess;
764 :
765 : // Untersuchtes Objekt
766 : const Any& mrInspectedObject;
767 :
768 : // Statische Daten der Introspection
769 : rtl::Reference< IntrospectionAccessStatic_Impl > mpStaticImpl;
770 :
771 : // Objekt als Interface
772 : Reference<XInterface> mxIface;
773 :
774 : // Original-Interfaces des Objekts
775 : Reference<XElementAccess> mxObjElementAccess;
776 : Reference<XNameContainer> mxObjNameContainer;
777 : Reference<XNameAccess> mxObjNameAccess;
778 : Reference<XIndexAccess> mxObjIndexAccess;
779 : Reference<XIndexContainer> mxObjIndexContainer;
780 : Reference<XEnumerationAccess> mxObjEnumerationAccess;
781 : Reference<XIdlArray> mxObjIdlArray;
782 :
783 : public:
784 : ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
785 : const Any& obj,
786 : rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ );
787 :
788 : // Methoden von XInterface
789 : virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
790 70424 : virtual void SAL_CALL acquire() throw() SAL_OVERRIDE { OWeakObject::acquire(); }
791 70344 : virtual void SAL_CALL release() throw() SAL_OVERRIDE { OWeakObject::release(); }
792 :
793 : // Methoden von XPropertySet
794 : virtual Reference<XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( RuntimeException, std::exception ) SAL_OVERRIDE;
795 : virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName, const Any& aValue)
796 : throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
797 : virtual Any SAL_CALL getPropertyValue(const OUString& aPropertyName)
798 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
799 : virtual void SAL_CALL addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
800 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
801 : virtual void SAL_CALL removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
802 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
803 : virtual void SAL_CALL addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
804 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
805 : virtual void SAL_CALL removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
806 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
807 :
808 : // Methoden von XFastPropertySet
809 : virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const Any& aValue)
810 : throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
811 : virtual Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle)
812 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
813 :
814 : // Methoden von XPropertySetInfo
815 : virtual Sequence< Property > SAL_CALL getProperties(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
816 : virtual Property SAL_CALL getPropertyByName(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
817 : virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
818 :
819 : // Methoden von XElementAccess
820 : virtual Type SAL_CALL getElementType(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
821 : virtual sal_Bool SAL_CALL hasElements(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
822 :
823 : // Methoden von XNameAccess
824 : virtual Any SAL_CALL getByName(const OUString& Name)
825 : throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
826 : virtual Sequence< OUString > SAL_CALL getElementNames(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
827 : virtual sal_Bool SAL_CALL hasByName(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
828 :
829 : // Methoden von XNameContainer
830 : virtual void SAL_CALL insertByName(const OUString& Name, const Any& Element)
831 : throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
832 : virtual void SAL_CALL replaceByName(const OUString& Name, const Any& Element)
833 : throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
834 : virtual void SAL_CALL removeByName(const OUString& Name)
835 : throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
836 :
837 : // Methoden von XIndexAccess
838 : virtual sal_Int32 SAL_CALL getCount(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
839 : virtual Any SAL_CALL getByIndex(sal_Int32 Index)
840 : throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
841 :
842 : // Methoden von XIndexContainer
843 : virtual void SAL_CALL insertByIndex(sal_Int32 Index, const Any& Element)
844 : throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
845 : virtual void SAL_CALL replaceByIndex(sal_Int32 Index, const Any& Element)
846 : throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
847 : virtual void SAL_CALL removeByIndex(sal_Int32 Index)
848 : throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
849 :
850 : // Methoden von XEnumerationAccess
851 : virtual Reference<XEnumeration> SAL_CALL createEnumeration(void) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
852 :
853 : // Methoden von XIdlArray
854 : virtual void SAL_CALL realloc(Any& array, sal_Int32 length)
855 : throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
856 : virtual sal_Int32 SAL_CALL getLen(const Any& array) throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
857 : virtual Any SAL_CALL get(const Any& array, sal_Int32 index)
858 : throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception ) SAL_OVERRIDE;
859 : virtual void SAL_CALL set(Any& array, sal_Int32 index, const Any& value)
860 : throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception ) SAL_OVERRIDE;
861 : };
862 :
863 10868 : ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
864 : const Any& obj,
865 : rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ )
866 10868 : : mpAccess( pAccess_), mrInspectedObject( obj ), mpStaticImpl( pStaticImpl_ )
867 : {
868 : // Objekt als Interfaceholen
869 10868 : TypeClass eType = mrInspectedObject.getValueType().getTypeClass();
870 10868 : if( eType == TypeClass_INTERFACE )
871 : {
872 5170 : mxIface = *( Reference< XInterface >*)mrInspectedObject.getValue();
873 :
874 5170 : mxObjElementAccess = Reference<XElementAccess>::query( mxIface );
875 5170 : mxObjNameAccess = Reference<XNameAccess>::query( mxIface );
876 5170 : mxObjNameContainer = Reference<XNameContainer>::query( mxIface );
877 5170 : mxObjIndexAccess = Reference<XIndexAccess>::query( mxIface );
878 5170 : mxObjIndexContainer = Reference<XIndexContainer>::query( mxIface );
879 5170 : mxObjEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface );
880 5170 : mxObjIdlArray = Reference<XIdlArray>::query( mxIface );
881 : }
882 10868 : }
883 :
884 : // Methoden von XInterface
885 34484 : Any SAL_CALL ImplIntrospectionAdapter::queryInterface( const Type& rType )
886 : throw( RuntimeException, std::exception )
887 : {
888 : Any aRet( ::cppu::queryInterface(
889 : rType,
890 : static_cast< XPropertySet * >( this ),
891 : static_cast< XFastPropertySet * >( this ),
892 34484 : static_cast< XPropertySetInfo * >( this ) ) );
893 34484 : if( !aRet.hasValue() )
894 24062 : aRet = OWeakObject::queryInterface( rType );
895 :
896 34484 : if( !aRet.hasValue() )
897 : {
898 : // Wrapper fuer die Objekt-Interfaces
899 22588 : if( ( mxObjElementAccess.is() && (aRet = ::cppu::queryInterface
900 1022 : ( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() )
901 13464 : || ( mxObjNameAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() )
902 13368 : || ( mxObjNameContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() )
903 13280 : || ( mxObjIndexAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() )
904 13276 : || ( mxObjIndexContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() )
905 13276 : || ( mxObjEnumerationAccess .is() && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() )
906 26836 : || ( mxObjIdlArray.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() )
907 : )
908 : {
909 : }
910 : }
911 34484 : return aRet;
912 : }
913 :
914 :
915 :
916 : //*** Implementation von ImplIntrospectionAdapter ***
917 :
918 :
919 : // Methoden von XPropertySet
920 8 : Reference<XPropertySetInfo> ImplIntrospectionAdapter::getPropertySetInfo(void)
921 : throw( RuntimeException, std::exception )
922 : {
923 8 : return (XPropertySetInfo *)this;
924 : }
925 :
926 1258 : void ImplIntrospectionAdapter::setPropertyValue(const OUString& aPropertyName, const Any& aValue)
927 : throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception )
928 : {
929 1258 : mpStaticImpl->setPropertyValue( mrInspectedObject, aPropertyName, aValue );
930 1258 : }
931 :
932 3908 : Any ImplIntrospectionAdapter::getPropertyValue(const OUString& aPropertyName)
933 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
934 : {
935 3908 : return mpStaticImpl->getPropertyValue( mrInspectedObject, aPropertyName );
936 : }
937 :
938 0 : void ImplIntrospectionAdapter::addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
939 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
940 : {
941 0 : if( mxIface.is() )
942 : {
943 : Reference<XPropertySet> xPropSet =
944 0 : Reference<XPropertySet>::query( mxIface );
945 : //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
946 0 : if( xPropSet.is() )
947 0 : xPropSet->addPropertyChangeListener(aPropertyName, aListener);
948 : }
949 0 : }
950 :
951 0 : void ImplIntrospectionAdapter::removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
952 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
953 : {
954 0 : if( mxIface.is() )
955 : {
956 : Reference<XPropertySet> xPropSet =
957 0 : Reference<XPropertySet>::query( mxIface );
958 : //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
959 0 : if( xPropSet.is() )
960 0 : xPropSet->removePropertyChangeListener(aPropertyName, aListener);
961 : }
962 0 : }
963 :
964 0 : void ImplIntrospectionAdapter::addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
965 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
966 : {
967 0 : if( mxIface.is() )
968 : {
969 : Reference<XPropertySet> xPropSet =
970 0 : Reference<XPropertySet>::query( mxIface );
971 : //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
972 0 : if( xPropSet.is() )
973 0 : xPropSet->addVetoableChangeListener(aPropertyName, aListener);
974 : }
975 0 : }
976 :
977 0 : void ImplIntrospectionAdapter::removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
978 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
979 : {
980 0 : if( mxIface.is() )
981 : {
982 : Reference<XPropertySet> xPropSet =
983 0 : Reference<XPropertySet>::query( mxIface );
984 0 : if( xPropSet.is() )
985 0 : xPropSet->removeVetoableChangeListener(aPropertyName, aListener);
986 : }
987 0 : }
988 :
989 :
990 : // Methoden von XFastPropertySet
991 0 : void ImplIntrospectionAdapter::setFastPropertyValue(sal_Int32, const Any&)
992 : throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception )
993 : {
994 0 : }
995 :
996 0 : Any ImplIntrospectionAdapter::getFastPropertyValue(sal_Int32)
997 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
998 : {
999 0 : return Any();
1000 : }
1001 :
1002 : // Methoden von XPropertySetInfo
1003 8 : Sequence< Property > ImplIntrospectionAdapter::getProperties(void) throw( RuntimeException, std::exception )
1004 : {
1005 8 : return mpStaticImpl->getProperties();
1006 : }
1007 :
1008 0 : Property ImplIntrospectionAdapter::getPropertyByName(const OUString& Name)
1009 : throw( RuntimeException, std::exception )
1010 : {
1011 0 : return mpAccess->getProperty( Name, PropertyConcept::ALL );
1012 : }
1013 :
1014 0 : sal_Bool ImplIntrospectionAdapter::hasPropertyByName(const OUString& Name)
1015 : throw( RuntimeException, std::exception )
1016 : {
1017 0 : return mpAccess->hasProperty( Name, PropertyConcept::ALL );
1018 : }
1019 :
1020 : // Methoden von XElementAccess
1021 0 : Type ImplIntrospectionAdapter::getElementType(void) throw( RuntimeException, std::exception )
1022 : {
1023 0 : return mxObjElementAccess->getElementType();
1024 : }
1025 :
1026 0 : sal_Bool ImplIntrospectionAdapter::hasElements(void) throw( RuntimeException, std::exception )
1027 : {
1028 0 : return mxObjElementAccess->hasElements();
1029 : }
1030 :
1031 : // Methoden von XNameAccess
1032 0 : Any ImplIntrospectionAdapter::getByName(const OUString& Name)
1033 : throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
1034 : {
1035 0 : return mxObjNameAccess->getByName( Name );
1036 : }
1037 :
1038 0 : Sequence< OUString > ImplIntrospectionAdapter::getElementNames(void)
1039 : throw( RuntimeException, std::exception )
1040 : {
1041 0 : return mxObjNameAccess->getElementNames();
1042 : }
1043 :
1044 2 : sal_Bool ImplIntrospectionAdapter::hasByName(const OUString& Name)
1045 : throw( RuntimeException, std::exception )
1046 : {
1047 2 : return mxObjNameAccess->hasByName( Name );
1048 : }
1049 :
1050 : // Methoden von XNameContainer
1051 0 : void ImplIntrospectionAdapter::insertByName(const OUString& Name, const Any& Element)
1052 : throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception )
1053 : {
1054 0 : mxObjNameContainer->insertByName( Name, Element );
1055 0 : }
1056 :
1057 0 : void ImplIntrospectionAdapter::replaceByName(const OUString& Name, const Any& Element)
1058 : throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
1059 : {
1060 0 : mxObjNameContainer->replaceByName( Name, Element );
1061 0 : }
1062 :
1063 0 : void ImplIntrospectionAdapter::removeByName(const OUString& Name)
1064 : throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
1065 : {
1066 0 : mxObjNameContainer->removeByName( Name );
1067 0 : }
1068 :
1069 : // Methoden von XIndexAccess
1070 : // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const
1071 0 : sal_Int32 ImplIntrospectionAdapter::getCount(void) throw( RuntimeException, std::exception )
1072 : {
1073 0 : return mxObjIndexAccess->getCount();
1074 : }
1075 :
1076 0 : Any ImplIntrospectionAdapter::getByIndex(sal_Int32 Index)
1077 : throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1078 : {
1079 0 : return mxObjIndexAccess->getByIndex( Index );
1080 : }
1081 :
1082 : // Methoden von XIndexContainer
1083 0 : void ImplIntrospectionAdapter::insertByIndex(sal_Int32 Index, const Any& Element)
1084 : throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1085 : {
1086 0 : mxObjIndexContainer->insertByIndex( Index, Element );
1087 0 : }
1088 :
1089 0 : void ImplIntrospectionAdapter::replaceByIndex(sal_Int32 Index, const Any& Element)
1090 : throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1091 : {
1092 0 : mxObjIndexContainer->replaceByIndex( Index, Element );
1093 0 : }
1094 :
1095 0 : void ImplIntrospectionAdapter::removeByIndex(sal_Int32 Index)
1096 : throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1097 : {
1098 0 : mxObjIndexContainer->removeByIndex( Index );
1099 0 : }
1100 :
1101 : // Methoden von XEnumerationAccess
1102 : // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const;
1103 0 : Reference<XEnumeration> ImplIntrospectionAdapter::createEnumeration(void) throw( RuntimeException, std::exception )
1104 : {
1105 0 : return mxObjEnumerationAccess->createEnumeration();
1106 : }
1107 :
1108 : // Methoden von XIdlArray
1109 0 : void ImplIntrospectionAdapter::realloc(Any& array, sal_Int32 length)
1110 : throw( IllegalArgumentException, RuntimeException, std::exception )
1111 : {
1112 0 : mxObjIdlArray->realloc( array, length );
1113 0 : }
1114 :
1115 0 : sal_Int32 ImplIntrospectionAdapter::getLen(const Any& array)
1116 : throw( IllegalArgumentException, RuntimeException, std::exception )
1117 : {
1118 0 : return mxObjIdlArray->getLen( array );
1119 : }
1120 :
1121 0 : Any ImplIntrospectionAdapter::get(const Any& array, sal_Int32 index)
1122 : throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception )
1123 : {
1124 0 : return mxObjIdlArray->get( array, index );
1125 : }
1126 :
1127 0 : void ImplIntrospectionAdapter::set(Any& array, sal_Int32 index, const Any& value)
1128 : throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception )
1129 : {
1130 0 : mxObjIdlArray->set( array, index, value );
1131 0 : }
1132 :
1133 :
1134 :
1135 : //*** Implementation von ImplIntrospectionAccess ***
1136 :
1137 :
1138 : // Methoden von XIntrospectionAccess
1139 0 : sal_Int32 ImplIntrospectionAccess::getSuppliedMethodConcepts(void)
1140 : throw( RuntimeException, std::exception )
1141 : {
1142 : return MethodConcept::DANGEROUS |
1143 : PROPERTY |
1144 : LISTENER |
1145 : ENUMERATION |
1146 : NAMECONTAINER |
1147 0 : INDEXCONTAINER;
1148 : }
1149 :
1150 0 : sal_Int32 ImplIntrospectionAccess::getSuppliedPropertyConcepts(void)
1151 : throw( RuntimeException, std::exception )
1152 : {
1153 : return PropertyConcept::DANGEROUS |
1154 : PROPERTYSET |
1155 : ATTRIBUTES |
1156 0 : METHODS;
1157 : }
1158 :
1159 2652 : Property ImplIntrospectionAccess::getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
1160 : throw( NoSuchElementException, RuntimeException, std::exception )
1161 : {
1162 2652 : Property aRet;
1163 2652 : sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
1164 2652 : bool bFound = false;
1165 2652 : if( i != -1 )
1166 : {
1167 2652 : sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
1168 2652 : if( (PropertyConcepts & nConcept) != 0 )
1169 : {
1170 2652 : const Property* pProps = mpStaticImpl->getProperties().getConstArray();
1171 2652 : aRet = pProps[ i ];
1172 2652 : bFound = true;
1173 : }
1174 : }
1175 2652 : if( !bFound )
1176 0 : throw NoSuchElementException() ;
1177 2652 : return aRet;
1178 : }
1179 :
1180 6930 : sal_Bool ImplIntrospectionAccess::hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
1181 : throw( RuntimeException, std::exception )
1182 : {
1183 6930 : sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
1184 6930 : bool bRet = false;
1185 6930 : if( i != -1 )
1186 : {
1187 4486 : sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
1188 4486 : if( (PropertyConcepts & nConcept) != 0 )
1189 4486 : bRet = true;
1190 : }
1191 6930 : return bRet;
1192 : }
1193 :
1194 0 : Sequence< Property > ImplIntrospectionAccess::getProperties(sal_Int32 PropertyConcepts)
1195 : throw( RuntimeException, std::exception )
1196 : {
1197 : // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
1198 : sal_Int32 nAllSupportedMask = PROPERTYSET |
1199 : ATTRIBUTES |
1200 0 : METHODS;
1201 0 : if( ( PropertyConcepts & nAllSupportedMask ) == nAllSupportedMask )
1202 : {
1203 0 : return mpStaticImpl->getProperties();
1204 : }
1205 :
1206 : // Gleiche Sequence wie beim vorigen mal?
1207 0 : if( mnLastPropertyConcept == PropertyConcepts )
1208 : {
1209 0 : return maLastPropertySeq;
1210 : }
1211 :
1212 : // Anzahl der zu liefernden Properties
1213 0 : sal_Int32 nCount = 0;
1214 :
1215 : // Es gibt zur Zeit keine DANGEROUS-Properties
1216 : // if( PropertyConcepts & DANGEROUS )
1217 : // nCount += mpStaticImpl->mnDangerousPropCount;
1218 0 : if( PropertyConcepts & PROPERTYSET )
1219 0 : nCount += mpStaticImpl->mnPropertySetPropCount;
1220 0 : if( PropertyConcepts & ATTRIBUTES )
1221 0 : nCount += mpStaticImpl->mnAttributePropCount;
1222 0 : if( PropertyConcepts & METHODS )
1223 0 : nCount += mpStaticImpl->mnMethodPropCount;
1224 :
1225 : // Sequence entsprechend der geforderten Anzahl reallocieren
1226 0 : ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen
1227 0 : pThis->maLastPropertySeq.realloc( nCount );
1228 0 : Property* pDestProps = pThis->maLastPropertySeq.getArray();
1229 :
1230 : // Alle Properties durchgehen und entsprechend der Concepte uebernehmen
1231 0 : Sequence<Property> aPropSeq = mpStaticImpl->getProperties();
1232 0 : const Property* pSourceProps = aPropSeq.getConstArray();
1233 0 : const sal_Int32* pConcepts = mpStaticImpl->getPropertyConcepts().getConstArray();
1234 0 : sal_Int32 nLen = aPropSeq.getLength();
1235 :
1236 0 : sal_Int32 iDest = 0;
1237 0 : for( sal_Int32 i = 0 ; i < nLen ; i++ )
1238 : {
1239 0 : sal_Int32 nConcept = pConcepts[ i ];
1240 0 : if( nConcept & PropertyConcepts )
1241 0 : pDestProps[ iDest++ ] = pSourceProps[ i ];
1242 : }
1243 :
1244 : // PropertyConcept merken, dies entspricht maLastPropertySeq
1245 0 : pThis->mnLastPropertyConcept = PropertyConcepts;
1246 :
1247 : // Zusammengebastelte Sequence liefern
1248 0 : return maLastPropertySeq;
1249 : }
1250 :
1251 2788 : Reference<XIdlMethod> ImplIntrospectionAccess::getMethod(const OUString& Name, sal_Int32 MethodConcepts)
1252 : throw( NoSuchMethodException, RuntimeException, std::exception )
1253 : {
1254 2788 : Reference<XIdlMethod> xRet;
1255 2788 : sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
1256 2788 : if( i != -1 )
1257 : {
1258 :
1259 2788 : sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
1260 2788 : if( (MethodConcepts & nConcept) != 0 )
1261 : {
1262 2788 : const Reference<XIdlMethod>* pMethods = mpStaticImpl->getMethods().getConstArray();
1263 2788 : xRet = pMethods[i];
1264 : }
1265 : }
1266 2788 : if( !xRet.is() )
1267 0 : throw NoSuchMethodException();
1268 2788 : return xRet;
1269 : }
1270 :
1271 4020 : sal_Bool ImplIntrospectionAccess::hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
1272 : throw( RuntimeException, std::exception )
1273 : {
1274 4020 : sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
1275 4020 : bool bRet = false;
1276 4020 : if( i != -1 )
1277 : {
1278 2788 : sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
1279 2788 : if( (MethodConcepts & nConcept) != 0 )
1280 2788 : bRet = true;
1281 : }
1282 4020 : return bRet;
1283 : }
1284 :
1285 484 : Sequence< Reference<XIdlMethod> > ImplIntrospectionAccess::getMethods(sal_Int32 MethodConcepts)
1286 : throw( RuntimeException, std::exception )
1287 : {
1288 484 : ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen
1289 :
1290 : // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
1291 : sal_Int32 nAllSupportedMask = MethodConcept::DANGEROUS |
1292 : PROPERTY |
1293 : LISTENER |
1294 : ENUMERATION |
1295 : NAMECONTAINER |
1296 : INDEXCONTAINER |
1297 484 : MethodConcept_NORMAL_IMPL;
1298 484 : if( ( MethodConcepts & nAllSupportedMask ) == nAllSupportedMask )
1299 : {
1300 54 : return mpStaticImpl->getMethods();
1301 : }
1302 :
1303 : // Gleiche Sequence wie beim vorigen mal?
1304 430 : if( mnLastMethodConcept == MethodConcepts )
1305 : {
1306 40 : return maLastMethodSeq;
1307 : }
1308 :
1309 : // Methoden-Sequences besorgen
1310 390 : Sequence< Reference<XIdlMethod> > aMethodSeq = mpStaticImpl->getMethods();
1311 390 : const Reference<XIdlMethod>* pSourceMethods = aMethodSeq.getConstArray();
1312 390 : const sal_Int32* pConcepts = mpStaticImpl->getMethodConcepts().getConstArray();
1313 390 : sal_Int32 nLen = aMethodSeq.getLength();
1314 :
1315 : // Sequence entsprechend der geforderten Anzahl reallocieren
1316 : // Anders als bei den Properties kann die Anzahl nicht durch
1317 : // Zaehler in inspect() vorher ermittelt werden, da Methoden
1318 : // mehreren Konzepten angehoeren koennen
1319 390 : pThis->maLastMethodSeq.realloc( nLen );
1320 390 : Reference<XIdlMethod>* pDestMethods = pThis->maLastMethodSeq.getArray();
1321 :
1322 : // Alle Methods durchgehen und entsprechend der Concepte uebernehmen
1323 390 : sal_Int32 iDest = 0;
1324 30502 : for( sal_Int32 i = 0 ; i < nLen ; i++ )
1325 : {
1326 30112 : sal_Int32 nConcept = pConcepts[ i ];
1327 30112 : if( nConcept & MethodConcepts )
1328 7188 : pDestMethods[ iDest++ ] = pSourceMethods[ i ];
1329 :
1330 : #if OSL_DEBUG_LEVEL > 0
1331 : static bool debug = false;
1332 : if ( debug )
1333 : {
1334 : // Methode mit Concepts ausgeben
1335 : const Reference< XIdlMethod >& rxMethod = pSourceMethods[ i ];
1336 : OString aNameStr = OUStringToOString( rxMethod->getName(), osl_getThreadTextEncoding() );
1337 : OString ConceptStr;
1338 : if( nConcept & MethodConcept::DANGEROUS )
1339 : ConceptStr += "DANGEROUS |";
1340 : if( nConcept & MethodConcept::PROPERTY )
1341 : ConceptStr += "PROPERTY |";
1342 : if( nConcept & MethodConcept::LISTENER )
1343 : ConceptStr += "LISTENER |";
1344 : if( nConcept & MethodConcept::ENUMERATION )
1345 : ConceptStr += "ENUMERATION |";
1346 : if( nConcept & MethodConcept::NAMECONTAINER )
1347 : ConceptStr += "NAMECONTAINER |";
1348 : if( nConcept & MethodConcept::INDEXCONTAINER )
1349 : ConceptStr += "INDEXCONTAINER |";
1350 : OSL_TRACE( "Method %ld: %s, Concepts = %s", i, aNameStr.getStr(), ConceptStr.getStr() );
1351 : }
1352 : #endif
1353 : }
1354 :
1355 : // Auf die richtige Laenge bringen
1356 390 : pThis->maLastMethodSeq.realloc( iDest );
1357 :
1358 : // MethodConcept merken, dies entspricht maLastMethodSeq
1359 390 : pThis->mnLastMethodConcept = MethodConcepts;
1360 :
1361 : // Zusammengebastelte Sequence liefern
1362 390 : return maLastMethodSeq;
1363 : }
1364 :
1365 18 : Sequence< Type > ImplIntrospectionAccess::getSupportedListeners(void)
1366 : throw( RuntimeException, std::exception )
1367 : {
1368 18 : return mpStaticImpl->getSupportedListeners();
1369 : }
1370 :
1371 11564 : Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type& rType )
1372 : throw( IllegalTypeException, RuntimeException, std::exception )
1373 : {
1374 : // Gibt es schon einen Adapter?
1375 11564 : Reference< XInterface > xAdapter( maAdapter );
1376 11564 : if( !xAdapter.is() )
1377 : {
1378 10868 : xAdapter = *( new ImplIntrospectionAdapter( this, maInspectedObject, mpStaticImpl ) );
1379 10868 : maAdapter = xAdapter;
1380 : }
1381 :
1382 11564 : Reference<XInterface> xRet;
1383 11564 : xAdapter->queryInterface( rType ) >>= xRet;
1384 11564 : return xRet;
1385 : }
1386 :
1387 : // Methoden von XMaterialHolder
1388 53134 : Any ImplIntrospectionAccess::getMaterial(void) throw(RuntimeException, std::exception)
1389 : {
1390 53134 : return maInspectedObject;
1391 : }
1392 :
1393 : // Hilfs-Funktion zur LowerCase-Wandlung eines OUString
1394 111652 : OUString toLower( const OUString& aUStr )
1395 : {
1396 : // Tabelle fuer XExactName pflegen
1397 111652 : OUString aOWStr( aUStr.getStr() );
1398 223304 : OUString aOWLowerStr = aOWStr.toAsciiLowerCase();
1399 111652 : OUString aLowerUStr( aOWLowerStr.getStr() );
1400 223304 : return aLowerUStr;
1401 : }
1402 :
1403 : // Methoden von XExactName
1404 4708 : OUString ImplIntrospectionAccess::getExactName( const OUString& rApproximateName ) throw( RuntimeException, std::exception )
1405 : {
1406 4708 : OUString aRetStr;
1407 : LowerToExactNameMap::iterator aIt =
1408 4708 : mpStaticImpl->maLowerToExactNameMap.find( toLower( rApproximateName ) );
1409 4708 : if( !( aIt == mpStaticImpl->maLowerToExactNameMap.end() ) )
1410 4386 : aRetStr = (*aIt).second;
1411 4708 : return aRetStr;
1412 : }
1413 :
1414 1412 : struct ClassKey {
1415 1162 : ClassKey(
1416 : css::uno::Reference<css::beans::XPropertySetInfo> const & theProperties,
1417 : css::uno::Reference<css::reflection::XIdlClass> const &
1418 : theImplementation,
1419 : css::uno::Sequence< css::uno::Reference<css::reflection::XIdlClass> >
1420 : const & theClasses):
1421 : properties(theProperties), implementation(theImplementation),
1422 1162 : classes(theClasses)
1423 1162 : {}
1424 :
1425 : css::uno::Reference<css::beans::XPropertySetInfo> properties;
1426 : css::uno::Reference<css::reflection::XIdlClass> implementation;
1427 : css::uno::Sequence< css::uno::Reference<css::reflection::XIdlClass> >
1428 : classes;
1429 : };
1430 :
1431 : struct ClassKeyLess {
1432 4317 : bool operator ()(ClassKey const & key1, ClassKey const & key2) const {
1433 4317 : if (key1.properties.get() < key2.properties.get()) {
1434 0 : return true;
1435 : }
1436 4317 : if (key1.properties.get() > key2.properties.get()) {
1437 0 : return false;
1438 : }
1439 4317 : if (key1.implementation.get() < key2.implementation.get()) {
1440 1726 : return true;
1441 : }
1442 2591 : if (key1.implementation.get() > key2.implementation.get()) {
1443 407 : return false;
1444 : }
1445 2184 : if (key1.classes.getLength() < key2.classes.getLength()) {
1446 0 : return true;
1447 : }
1448 2184 : if (key1.classes.getLength() > key2.classes.getLength()) {
1449 0 : return false;
1450 : }
1451 2216 : for (sal_Int32 i = 0; i != key1.classes.getLength(); ++i) {
1452 32 : if (key1.classes[i].get() < key2.classes[i].get()) {
1453 0 : return true;
1454 : }
1455 32 : if (key1.classes[i].get() > key2.classes[i].get()) {
1456 0 : return false;
1457 : }
1458 : }
1459 2184 : return false;
1460 : }
1461 : };
1462 :
1463 18982 : struct TypeKey {
1464 15766 : TypeKey(
1465 : css::uno::Reference<css::beans::XPropertySetInfo> const & theProperties,
1466 : css::uno::Sequence<css::uno::Type> const & theTypes):
1467 15766 : properties(theProperties)
1468 : {
1469 : //TODO: Could even sort the types lexicographically first, to increase
1470 : // the chance of matches between different implementations' getTypes(),
1471 : // but the old scheme of using getImplementationId() would have missed
1472 : // those matches, too:
1473 15766 : OUStringBuffer b;
1474 819572 : for (sal_Int32 i = 0; i != theTypes.getLength(); ++i) {
1475 803806 : b.append(theTypes[i].getTypeName());
1476 803806 : b.append('*'); // arbitrary delimiter not used by type grammar
1477 : }
1478 15766 : types = b.makeStringAndClear();
1479 15766 : }
1480 :
1481 : css::uno::Reference<css::beans::XPropertySetInfo> properties;
1482 : OUString types;
1483 : };
1484 :
1485 : struct TypeKeyLess {
1486 66895 : bool operator ()(TypeKey const & key1, TypeKey const & key2) const {
1487 66895 : if (key1.properties.get() < key2.properties.get()) {
1488 12484 : return true;
1489 : }
1490 54411 : if (key1.properties.get() > key2.properties.get()) {
1491 4363 : return false;
1492 : }
1493 50048 : return key1.types < key2.types;
1494 : }
1495 : };
1496 :
1497 684 : template<typename Key, typename Less> class Cache {
1498 : public:
1499 16928 : rtl::Reference<IntrospectionAccessStatic_Impl> find(Key const & key) const {
1500 16928 : typename Map::const_iterator i(map_.find(key));
1501 16928 : if (i == map_.end()) {
1502 896 : return rtl::Reference<IntrospectionAccessStatic_Impl>();
1503 : } else {
1504 16032 : if (i->second.hits < std::numeric_limits<unsigned>::max()) {
1505 16032 : ++i->second.hits;
1506 : }
1507 : assert(i->second.access.is());
1508 16032 : return i->second.access;
1509 : }
1510 : }
1511 :
1512 896 : void insert(
1513 : Key const & key,
1514 : rtl::Reference<IntrospectionAccessStatic_Impl> const & access)
1515 : {
1516 : assert(access.is());
1517 896 : typename Map::size_type const MAX = 100;
1518 : assert(map_.size() <= MAX);
1519 896 : if (map_.size() == MAX) {
1520 142 : typename Map::iterator del(map_.begin());
1521 14342 : for (typename Map::iterator i(map_.begin()); i != map_.end(); ++i) {
1522 14200 : if (i->second.hits < del->second.hits) {
1523 518 : del = i;
1524 : }
1525 : }
1526 142 : map_.erase(del);
1527 : }
1528 : bool ins = map_.insert(typename Map::value_type(key, Data(access)))
1529 896 : .second;
1530 : assert(ins); (void)ins;
1531 896 : }
1532 :
1533 348 : void clear() { map_.clear(); }
1534 :
1535 : private:
1536 4362 : struct Data {
1537 896 : explicit Data(
1538 : rtl::Reference<IntrospectionAccessStatic_Impl> const & theAccess):
1539 896 : access(theAccess), hits(1)
1540 896 : {}
1541 :
1542 : rtl::Reference<IntrospectionAccessStatic_Impl> access;
1543 : mutable unsigned hits;
1544 : };
1545 :
1546 : typedef std::map<Key, Data, Less> Map;
1547 :
1548 : Map map_;
1549 : };
1550 :
1551 : typedef
1552 : cppu::WeakComponentImplHelper2<
1553 : css::lang::XServiceInfo, css::beans::XIntrospection>
1554 : Implementation_Base;
1555 :
1556 328 : class Implementation: private cppu::BaseMutex, public Implementation_Base {
1557 : public:
1558 178 : explicit Implementation(
1559 : css::uno::Reference<css::uno::XComponentContext> const & context):
1560 : Implementation_Base(m_aMutex),
1561 178 : reflection_(css::reflection::theCoreReflection::get(context))
1562 178 : {}
1563 :
1564 : private:
1565 174 : virtual void SAL_CALL disposing() SAL_OVERRIDE {
1566 174 : reflection_.clear();
1567 174 : classCache_.clear();
1568 174 : typeCache_.clear();
1569 174 : }
1570 :
1571 0 : virtual OUString SAL_CALL getImplementationName()
1572 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
1573 0 : { return OUString("com.sun.star.comp.stoc.Introspection"); }
1574 :
1575 0 : virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
1576 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
1577 0 : { return cppu::supportsService(this, ServiceName); }
1578 :
1579 : virtual css::uno::Sequence<OUString> SAL_CALL
1580 0 : getSupportedServiceNames()
1581 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
1582 : {
1583 0 : Sequence<OUString> s(1);
1584 0 : s[0] = "com.sun.star.beans.Introspection";
1585 0 : return s;
1586 : }
1587 :
1588 : virtual css::uno::Reference<css::beans::XIntrospectionAccess> SAL_CALL
1589 : inspect(css::uno::Any const & aObject)
1590 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1591 :
1592 : css::uno::Reference<css::reflection::XIdlReflection> reflection_;
1593 : Cache<ClassKey, ClassKeyLess> classCache_;
1594 : Cache<TypeKey, TypeKeyLess> typeCache_;
1595 : };
1596 :
1597 32732 : css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
1598 : css::uno::Any const & aObject)
1599 : throw (css::uno::RuntimeException, std::exception)
1600 : {
1601 32732 : osl::MutexGuard g(m_aMutex);
1602 32732 : if (rBHelper.bDisposed) {
1603 : throw css::lang::DisposedException(
1604 0 : getImplementationName(), static_cast<OWeakObject *>(this));
1605 : }
1606 65464 : css::uno::Any aToInspectObj;
1607 65464 : css::uno::Type t;
1608 32732 : if (aObject >>= t) {
1609 : css::uno::Reference<css::reflection::XIdlClass> c(
1610 0 : reflection_->forName(t.getTypeName()));
1611 0 : if (!c.is()) {
1612 : SAL_WARN("stoc", "cannot reflect type " << t.getTypeName());
1613 0 : return css::uno::Reference<css::beans::XIntrospectionAccess>();
1614 : }
1615 0 : aToInspectObj <<= c;
1616 : } else {
1617 32732 : aToInspectObj = aObject;
1618 : }
1619 :
1620 : // Objekt untersuchen
1621 32732 : TypeClass eType = aToInspectObj.getValueType().getTypeClass();
1622 32732 : if( eType != TypeClass_INTERFACE && eType != TypeClass_STRUCT && eType != TypeClass_EXCEPTION )
1623 15804 : return css::uno::Reference<css::beans::XIntrospectionAccess>();
1624 :
1625 33856 : Reference<XInterface> x;
1626 16928 : if( eType == TypeClass_INTERFACE )
1627 : {
1628 : // Interface aus dem Any besorgen
1629 15786 : x = *(Reference<XInterface>*)aToInspectObj.getValue();
1630 15786 : if( !x.is() )
1631 0 : return css::uno::Reference<css::beans::XIntrospectionAccess>();
1632 : }
1633 :
1634 : // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz
1635 33856 : rtl::Reference< IntrospectionAccessStatic_Impl > pAccess;
1636 :
1637 : // Pruefen: Ist schon ein passendes Access-Objekt gecached?
1638 33856 : Sequence< Reference<XIdlClass> > SupportedClassSeq;
1639 33856 : Sequence< Type > SupportedTypesSeq;
1640 33856 : Reference<XTypeProvider> xTypeProvider;
1641 33856 : Reference<XIdlClass> xImplClass;
1642 33856 : Reference<XPropertySetInfo> xPropSetInfo;
1643 33856 : Reference<XPropertySet> xPropSet;
1644 :
1645 : // Look for interfaces XTypeProvider and PropertySet
1646 16928 : if( eType == TypeClass_INTERFACE )
1647 : {
1648 15786 : xTypeProvider = Reference<XTypeProvider>::query( x );
1649 15786 : if( xTypeProvider.is() )
1650 : {
1651 15766 : SupportedTypesSeq = xTypeProvider->getTypes();
1652 15766 : sal_Int32 nTypeCount = SupportedTypesSeq.getLength();
1653 15766 : if( nTypeCount )
1654 : {
1655 15766 : SupportedClassSeq.realloc( nTypeCount );
1656 15766 : Reference<XIdlClass>* pClasses = SupportedClassSeq.getArray();
1657 :
1658 15766 : const Type* pTypes = SupportedTypesSeq.getConstArray();
1659 819572 : for( sal_Int32 i = 0 ; i < nTypeCount ; i++ )
1660 : {
1661 803806 : pClasses[i] = reflection_->forName(pTypes[i].getTypeName());
1662 : }
1663 : // TODO: Caching!
1664 : }
1665 : } else {
1666 : SAL_WARN(
1667 : "stoc",
1668 : "object of type \"" << aToInspectObj.getValueTypeName()
1669 : << "\" lacks XTypeProvider");
1670 20 : xImplClass = reflection_->forName(aToInspectObj.getValueTypeName());
1671 20 : SupportedClassSeq.realloc(1);
1672 20 : SupportedClassSeq[0] = xImplClass;
1673 : }
1674 :
1675 15786 : xPropSet = Reference<XPropertySet>::query( x );
1676 : // Jetzt versuchen, das PropertySetInfo zu bekommen
1677 15786 : if( xPropSet.is() )
1678 11204 : xPropSetInfo = xPropSet->getPropertySetInfo();
1679 : } else {
1680 1142 : xImplClass = reflection_->forName(aToInspectObj.getValueTypeName());
1681 : }
1682 :
1683 16928 : if (xTypeProvider.is()) {
1684 15766 : TypeKey key(xPropSetInfo, xTypeProvider->getTypes());
1685 15766 : pAccess = typeCache_.find(key);
1686 15766 : if (pAccess.is()) {
1687 14940 : return new ImplIntrospectionAccess(aToInspectObj, pAccess);
1688 : }
1689 826 : pAccess = new IntrospectionAccessStatic_Impl(reflection_);
1690 826 : typeCache_.insert(key, pAccess);
1691 1162 : } else if (xImplClass.is()) {
1692 1162 : ClassKey key(xPropSetInfo, xImplClass, SupportedClassSeq);
1693 1162 : pAccess = classCache_.find(key);
1694 1162 : if (pAccess.is()) {
1695 1092 : return new ImplIntrospectionAccess(aToInspectObj, pAccess);
1696 : }
1697 70 : pAccess = new IntrospectionAccessStatic_Impl(reflection_);
1698 70 : classCache_.insert(key, pAccess);
1699 : }
1700 :
1701 : // Kein Access gecached -> neu anlegen
1702 : Property* pAllPropArray;
1703 : Reference<XInterface>* pInterfaces1;
1704 : Reference<XInterface>* pInterfaces2;
1705 : sal_Int16* pMapTypeArray;
1706 : sal_Int32* pPropertyConceptArray;
1707 : sal_Int32 i;
1708 :
1709 896 : if( !pAccess.is() )
1710 0 : pAccess = new IntrospectionAccessStatic_Impl( reflection_ );
1711 :
1712 : // Referenzen auf wichtige Daten von pAccess
1713 896 : sal_Int32& rPropCount = pAccess->mnPropCount;
1714 896 : IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap;
1715 896 : IntrospectionNameMap& rMethodNameMap = pAccess->maMethodNameMap;
1716 896 : LowerToExactNameMap& rLowerToExactNameMap = pAccess->maLowerToExactNameMap;
1717 :
1718 : // Schon mal Pointer auf das eigene Property-Feld holen
1719 896 : pAllPropArray = pAccess->maAllPropertySeq.getArray();
1720 896 : pInterfaces1 = pAccess->aInterfaceSeq1.getArray();
1721 896 : pInterfaces2 = pAccess->aInterfaceSeq2.getArray();
1722 896 : pMapTypeArray = pAccess->maMapTypeSeq.getArray();
1723 896 : pPropertyConceptArray = pAccess->maPropertyConceptSeq.getArray();
1724 :
1725 :
1726 : //*** Analyse vornehmen ***
1727 :
1728 896 : if( eType == TypeClass_INTERFACE )
1729 : {
1730 : // Zunaechst nach speziellen Interfaces suchen, die fuer
1731 : // die Introspection von besonderer Bedeutung sind.
1732 :
1733 : // XPropertySet vorhanden?
1734 830 : if( xPropSet.is() && xPropSetInfo.is() )
1735 : {
1736 : // Gibt es auch ein FastPropertySet?
1737 468 : Reference<XFastPropertySet> xDummy = Reference<XFastPropertySet>::query( x );
1738 468 : bool bFast = pAccess->mbFastPropSet = xDummy.is();
1739 :
1740 936 : Sequence<Property> aPropSeq = xPropSetInfo->getProperties();
1741 468 : const Property* pProps = aPropSeq.getConstArray();
1742 468 : sal_Int32 nLen = aPropSeq.getLength();
1743 :
1744 : // Bei FastPropertySet muessen wir uns die Original-Handles merken
1745 468 : if( bFast )
1746 190 : pAccess->mpOrgPropertyHandleArray = new sal_Int32[ nLen ];
1747 :
1748 21744 : for( i = 0 ; i < nLen ; i++ )
1749 : {
1750 : // Property in eigene Liste uebernehmen
1751 : pAccess->checkPropertyArraysSize
1752 21276 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
1753 21276 : Property& rProp = pAllPropArray[ rPropCount ];
1754 21276 : rProp = pProps[ i ];
1755 :
1756 21276 : if( bFast )
1757 10592 : pAccess->mpOrgPropertyHandleArray[ i ] = rProp.Handle;
1758 :
1759 : // PropCount als Handle fuer das eigene FastPropertySet eintragen
1760 21276 : rProp.Handle = rPropCount;
1761 :
1762 : // Art der Property merken
1763 21276 : pMapTypeArray[ rPropCount ] = MAP_PROPERTY_SET;
1764 21276 : pPropertyConceptArray[ rPropCount ] = PROPERTYSET;
1765 21276 : pAccess->mnPropertySetPropCount++;
1766 :
1767 : // Namen in Hashtable eintragen, wenn nicht schon bekannt
1768 21276 : OUString aPropName = rProp.Name;
1769 :
1770 : // Haben wir den Namen schon?
1771 21276 : IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
1772 21276 : if( aIt == rPropNameMap.end() )
1773 : {
1774 : // Neuer Eintrag in die Hashtable
1775 21276 : rPropNameMap[ aPropName ] = rPropCount;
1776 :
1777 : // Tabelle fuer XExactName pflegen
1778 21276 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
1779 : }
1780 : else
1781 : {
1782 : SAL_WARN( "stoc", "Introspection: Property \"" <<
1783 : aPropName << "\" found more than once in PropertySet" );
1784 : }
1785 :
1786 : // Count pflegen
1787 21276 : rPropCount++;
1788 21744 : }
1789 : }
1790 :
1791 : // Indizes in die Export-Tabellen
1792 830 : sal_Int32 iAllExportedMethod = 0;
1793 830 : sal_Int32 iAllSupportedListener = 0;
1794 :
1795 830 : std::set<OUString> seen;
1796 :
1797 : // Flag, ob XInterface-Methoden erfasst werden sollen
1798 : // (das darf nur einmal erfolgen, initial zulassen)
1799 830 : bool bXInterfaceIsInvalid = false;
1800 :
1801 : // Flag, ob die XInterface-Methoden schon erfasst wurden. Wenn sal_True,
1802 : // wird bXInterfaceIsInvalid am Ende der Iface-Schleife aktiviert und
1803 : // XInterface-Methoden werden danach abgeklemmt.
1804 830 : bool bFoundXInterface = false;
1805 :
1806 830 : sal_Int32 nClassCount = SupportedClassSeq.getLength();
1807 23654 : for( sal_Int32 nIdx = 0 ; nIdx < nClassCount; nIdx++ )
1808 : {
1809 22824 : Reference<XIdlClass> xImplClass2 = SupportedClassSeq.getConstArray()[nIdx];
1810 95718 : while( xImplClass2.is() )
1811 : {
1812 : // Interfaces der Implementation holen
1813 50070 : Sequence< Reference<XIdlClass> > aClassSeq = xImplClass2->getInterfaces();
1814 50070 : sal_Int32 nIfaceCount = aClassSeq.getLength();
1815 :
1816 50070 : aClassSeq.realloc( nIfaceCount + 1 );
1817 50070 : aClassSeq.getArray()[ nIfaceCount ] = xImplClass2;
1818 50070 : nIfaceCount++;
1819 :
1820 50070 : const Reference<XIdlClass>* pParamArray = aClassSeq.getConstArray();
1821 :
1822 100140 : for( sal_Int32 j = 0 ; j < nIfaceCount ; j++ )
1823 : {
1824 50070 : const Reference<XIdlClass>& rxIfaceClass = pParamArray[j];
1825 50070 : if (!seen.insert(rxIfaceClass->getName()).second) {
1826 25504 : continue;
1827 : }
1828 :
1829 : // 2. Fields als Properties registrieren
1830 :
1831 : // Felder holen
1832 24566 : Sequence< Reference<XIdlField> > fields = rxIfaceClass->getFields();
1833 24566 : const Reference<XIdlField>* pFields = fields.getConstArray();
1834 24566 : sal_Int32 nLen = fields.getLength();
1835 :
1836 29288 : for( i = 0 ; i < nLen ; i++ )
1837 : {
1838 4722 : Reference<XIdlField> xField = pFields[i];
1839 7692 : Reference<XIdlClass> xPropType = xField->getType();
1840 :
1841 : // Ist die PropertySequence gross genug?
1842 : pAccess->checkPropertyArraysSize
1843 4722 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
1844 :
1845 : // In eigenes Property-Array eintragen
1846 4722 : Property& rProp = pAllPropArray[ rPropCount ];
1847 7692 : OUString aFieldName = xField->getName();
1848 4722 : rProp.Name = aFieldName;
1849 4722 : rProp.Handle = rPropCount;
1850 7692 : Type aFieldType( xPropType->getTypeClass(), xPropType->getName() );
1851 4722 : rProp.Type = aFieldType;
1852 4722 : FieldAccessMode eAccessMode = xField->getAccessMode();
1853 1390 : rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
1854 : eAccessMode == FieldAccessMode_CONST)
1855 8054 : ? READONLY : 0;
1856 :
1857 : // Namen in Hashtable eintragen
1858 7692 : OUString aPropName = rProp.Name;
1859 :
1860 : // Haben wir den Namen schon?
1861 4722 : IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
1862 4722 : if( !( aIt == rPropNameMap.end() ) )
1863 1752 : continue;
1864 :
1865 : // Neuer Eintrag in die Hashtable
1866 2970 : rPropNameMap[ aPropName ] = rPropCount;
1867 :
1868 : // Tabelle fuer XExactName pflegen
1869 2970 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
1870 :
1871 : // Field merken
1872 2970 : pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
1873 5940 : pInterfaces1, rPropCount );
1874 2970 : pInterfaces1[ rPropCount ] = xField;
1875 :
1876 : // Art der Property merken
1877 2970 : pMapTypeArray[ rPropCount ] = MAP_FIELD;
1878 2970 : pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
1879 2970 : pAccess->mnAttributePropCount++;
1880 :
1881 : // Count pflegen
1882 2970 : rPropCount++;
1883 2970 : }
1884 :
1885 :
1886 :
1887 : // 3. Methoden
1888 :
1889 : // Zaehler fuer die gefundenen Listener
1890 24566 : sal_Int32 nListenerCount = 0;
1891 :
1892 : // Alle Methoden holen und merken
1893 49132 : Sequence< Reference<XIdlMethod> > methods = rxIfaceClass->getMethods();
1894 24566 : const Reference<XIdlMethod>* pSourceMethods = methods.getConstArray();
1895 24566 : sal_Int32 nSourceMethodCount = methods.getLength();
1896 :
1897 : // 3. a) get/set- und Listener-Methoden suchen
1898 :
1899 : // Feld fuer Infos ueber die Methoden anlegen, damit spaeter leicht die Methoden
1900 : // gefunden werden koennen, die nicht im Zusammenhang mit Properties oder Listenern
1901 : // stehen. NEU: auch MethodConceptArray initialisieren
1902 : enum MethodType
1903 : {
1904 : STANDARD_METHOD, // normale Methode, kein Bezug zu Properties oder Listenern
1905 : GETSET_METHOD, // gehoert zu einer get/set-Property
1906 : ADD_LISTENER_METHOD, // add-Methode einer Listener-Schnittstelle
1907 : REMOVE_LISTENER_METHOD, // remove-Methode einer Listener-Schnittstelle
1908 : INVALID_METHOD // Methode, deren Klasse nicht beruecksichtigt wird, z.B. XPropertySet
1909 : };
1910 24566 : MethodType* pMethodTypes = new MethodType[ nSourceMethodCount ];
1911 24566 : sal_Int32* pLocalMethodConcepts = new sal_Int32[ nSourceMethodCount ];
1912 181156 : for( i = 0 ; i < nSourceMethodCount ; i++ )
1913 : {
1914 156590 : pMethodTypes[ i ] = STANDARD_METHOD;
1915 156590 : pLocalMethodConcepts[ i ] = 0;
1916 : }
1917 :
1918 49132 : OUString aMethName;
1919 49132 : OUString aPropName;
1920 49132 : OUString aStartStr;
1921 181156 : for( i = 0 ; i < nSourceMethodCount ; i++ )
1922 : {
1923 : // Methode ansprechen
1924 156590 : const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
1925 156590 : sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
1926 :
1927 : // Namen besorgen
1928 156590 : aMethName = rxMethod_i->getName();
1929 :
1930 : // Methoden katalogisieren
1931 : // Alle (?) Methoden von XInterface filtern, damit z.B. nicht
1932 : // vom Scripting aus acquire oder release gerufen werden kann
1933 : rtl::OUString className(
1934 156590 : rxMethod_i->getDeclaringClass()->getName());
1935 156590 : if (className == "com.sun.star.uno.XInterface") {
1936 73698 : bFoundXInterface = true;
1937 :
1938 73698 : if( bXInterfaceIsInvalid )
1939 : {
1940 71208 : pMethodTypes[ i ] = INVALID_METHOD;
1941 71208 : continue;
1942 : }
1943 : else
1944 : {
1945 2490 : if( aMethName != "queryInterface" )
1946 : {
1947 1660 : rMethodConcept_i |= MethodConcept::DANGEROUS;
1948 1660 : continue;
1949 : }
1950 : }
1951 82892 : } else if (className == "com.sun.star.uno.XAggregation")
1952 : {
1953 780 : if( aMethName == "setDelegator" )
1954 : {
1955 390 : rMethodConcept_i |= MethodConcept::DANGEROUS;
1956 390 : continue;
1957 : }
1958 82112 : } else if (className
1959 : == "com.sun.star.container.XElementAccess")
1960 : {
1961 : rMethodConcept_i |= ( NAMECONTAINER |
1962 : INDEXCONTAINER |
1963 1592 : ENUMERATION );
1964 80520 : } else if ((className
1965 80520 : == "com.sun.star.container.XNameContainer")
1966 160920 : || (className
1967 80400 : == "com.sun.star.container.XNameAccess"))
1968 : {
1969 1764 : rMethodConcept_i |= NAMECONTAINER;
1970 78756 : } else if ((className
1971 78756 : == "com.sun.star.container.XIndexContainer")
1972 157512 : || (className
1973 78756 : == "com.sun.star.container.XIndexAccess"))
1974 : {
1975 24 : rMethodConcept_i |= INDEXCONTAINER;
1976 78732 : } else if (className
1977 : == "com.sun.star.container.XEnumerationAccess")
1978 : {
1979 88 : rMethodConcept_i |= ENUMERATION;
1980 : }
1981 :
1982 : // Wenn der Name zu kurz ist, wird's sowieso nichts
1983 83332 : if( aMethName.getLength() <= 3 )
1984 30 : continue;
1985 :
1986 : // Ist es eine get-Methode?
1987 83302 : aStartStr = aMethName.copy( 0, 3 );
1988 83302 : if( aStartStr == "get" )
1989 : {
1990 : // Namen der potentiellen Property
1991 28178 : aPropName = aMethName.copy( 3 );
1992 :
1993 : // get-Methode darf keinen Parameter haben
1994 28178 : Sequence< Reference<XIdlClass> > getParams = rxMethod_i->getParameterTypes();
1995 28178 : if( getParams.getLength() > 0 )
1996 : {
1997 8792 : continue;
1998 : }
1999 :
2000 : // Haben wir den Namen schon?
2001 19386 : IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2002 19386 : if( !( aIt == rPropNameMap.end() ) )
2003 : {
2004 : /* TODO
2005 : OSL_TRACE(
2006 : String( "Introspection: Property \"" ) +
2007 : OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2008 : String( "\" found more than once" ) );
2009 : */
2010 4032 : continue;
2011 : }
2012 :
2013 : // Eine readonly-Property ist es jetzt mindestens schon
2014 15354 : rMethodConcept_i |= PROPERTY;
2015 :
2016 15354 : pMethodTypes[i] = GETSET_METHOD;
2017 30708 : Reference<XIdlClass> xGetRetType = rxMethod_i->getReturnType();
2018 :
2019 : // Ist die PropertySequence gross genug?
2020 : pAccess->checkPropertyArraysSize
2021 15354 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2022 :
2023 : // In eigenes Property-Array eintragen
2024 15354 : Property& rProp = pAllPropArray[ rPropCount ];
2025 15354 : rProp.Name = aPropName;
2026 15354 : rProp.Handle = rPropCount;
2027 15354 : rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
2028 15354 : rProp.Attributes = READONLY;
2029 :
2030 : // Neuer Eintrag in die Hashtable
2031 15354 : rPropNameMap[ aPropName ] = rPropCount;
2032 :
2033 : // Tabelle fuer XExactName pflegen
2034 15354 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2035 :
2036 : // get-Methode merken
2037 15354 : pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
2038 30708 : pInterfaces1, rPropCount );
2039 15354 : pInterfaces1[ rPropCount ] = rxMethod_i;
2040 :
2041 : // Art der Property merken
2042 15354 : pMapTypeArray[ rPropCount ] = MAP_GETSET;
2043 15354 : pPropertyConceptArray[ rPropCount ] = METHODS;
2044 15354 : pAccess->mnMethodPropCount++;
2045 :
2046 : // Passende set-Methode suchen
2047 : sal_Int32 k;
2048 154276 : for( k = 0 ; k < nSourceMethodCount ; k++ )
2049 : {
2050 : // Methode ansprechen
2051 138922 : const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
2052 :
2053 : // Nur Methoden nehmen, die nicht schon zugeordnet sind
2054 138922 : if( k == i || pMethodTypes[k] != STANDARD_METHOD )
2055 211450 : continue;
2056 :
2057 : // Name holen und auswerten
2058 64064 : OUString aMethName2 = rxMethod_k->getName();
2059 66394 : OUString aStartStr2 = aMethName2.copy( 0, 3 );
2060 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2061 64064 : if( !( aStartStr2 == "set" ) )
2062 57360 : continue;
2063 :
2064 : // Ist es denn der gleiche Name?
2065 9034 : OUString aPropName2 = aMethName2.copy( 3 );
2066 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2067 6704 : if( !( aPropName == aPropName2 ) )
2068 4176 : continue;
2069 :
2070 : // set-Methode muss void returnen
2071 4858 : Reference<XIdlClass> xSetRetType = rxMethod_k->getReturnType();
2072 2528 : if( xSetRetType->getTypeClass() != TypeClass_VOID )
2073 : {
2074 132 : continue;
2075 : }
2076 :
2077 : // set-Methode darf nur einen Parameter haben
2078 4726 : Sequence< Reference<XIdlClass> > setParams = rxMethod_k->getParameterTypes();
2079 2396 : sal_Int32 nParamCount = setParams.getLength();
2080 2396 : if( nParamCount != 1 )
2081 : {
2082 66 : continue;
2083 : }
2084 :
2085 : // Jetzt muss nur noch der return-Typ dem Parameter-Typ entsprechen
2086 2330 : const Reference<XIdlClass>* pParamArray2 = setParams.getConstArray();
2087 4660 : Reference<XIdlClass> xParamType = pParamArray2[ 0 ];
2088 2330 : if( xParamType->equals( xGetRetType ) )
2089 : {
2090 2330 : pLocalMethodConcepts[ k ] = PROPERTY;
2091 :
2092 2330 : pMethodTypes[k] = GETSET_METHOD;
2093 :
2094 : // ReadOnly-Flag wieder loschen
2095 2330 : rProp.Attributes &= ~READONLY;
2096 :
2097 : // set-Methode merken
2098 2330 : pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
2099 4660 : pInterfaces2, rPropCount );
2100 2330 : pInterfaces2[ rPropCount ] = rxMethod_k;
2101 : }
2102 2330 : }
2103 :
2104 : // Count pflegen
2105 30708 : rPropCount++;
2106 : }
2107 :
2108 : // Ist es eine addListener-Methode?
2109 55124 : else if( aStartStr == "add" )
2110 : {
2111 8032 : OUString aListenerStr( "Listener" );
2112 :
2113 : // Namen der potentiellen Property
2114 8032 : sal_Int32 nStrLen = aMethName.getLength();
2115 8032 : sal_Int32 nCopyLen = nStrLen - aListenerStr.getLength();
2116 14938 : OUString aEndStr = aMethName.copy( nCopyLen > 0 ? nCopyLen : 0 );
2117 :
2118 : // Endet das Teil auf Listener?
2119 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2120 8032 : if( !( aEndStr == aListenerStr ) )
2121 1126 : continue;
2122 :
2123 : // Welcher Listener?
2124 13812 : OUString aListenerName = aMethName.copy( 3, nStrLen - aListenerStr.getLength() - 3 );
2125 :
2126 : // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
2127 : // - Rueckgabe-Typ
2128 : // - Anzahl und Art der Parameter
2129 :
2130 :
2131 : // Passende remove-Methode suchen, sonst gilt's nicht
2132 : sal_Int32 k;
2133 85722 : for( k = 0 ; k < nSourceMethodCount ; k++ )
2134 : {
2135 : // Methode ansprechen
2136 78816 : const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
2137 :
2138 : // Nur Methoden nehmen, die nicht schon zugeordnet sind
2139 78816 : if( k == i || pMethodTypes[k] != STANDARD_METHOD )
2140 106978 : continue;
2141 :
2142 : // Name holen und auswerten
2143 43748 : OUString aMethName2 = rxMethod_k->getName();
2144 43748 : sal_Int32 nNameLen = aMethName2.getLength();
2145 43748 : sal_Int32 nCopyLen2 = (nNameLen < 6) ? nNameLen : 6;
2146 50654 : OUString aStartStr2 = aMethName2.copy( 0, nCopyLen2 );
2147 50654 : OUString aRemoveStr("remove" );
2148 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2149 43748 : if( !( aStartStr2 == aRemoveStr ) )
2150 33072 : continue;
2151 :
2152 : // Ist es denn der gleiche Listener?
2153 10676 : if( aMethName2.getLength() - aRemoveStr.getLength() <= aListenerStr.getLength() )
2154 324 : continue;
2155 : OUString aListenerName2 = aMethName2.copy
2156 17258 : ( 6, aMethName2.getLength() - aRemoveStr.getLength() - aListenerStr.getLength() );
2157 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2158 10352 : if( !( aListenerName == aListenerName2 ) )
2159 3446 : continue;
2160 :
2161 : // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
2162 : // - Rueckgabe-Typ
2163 : // - Anzahl und Art der Parameter
2164 :
2165 :
2166 : // Methoden sind als Listener-Schnittstelle erkannt
2167 6906 : rMethodConcept_i |= LISTENER;
2168 6906 : pLocalMethodConcepts[ k ] |= LISTENER;
2169 :
2170 6906 : pMethodTypes[i] = ADD_LISTENER_METHOD;
2171 6906 : pMethodTypes[k] = REMOVE_LISTENER_METHOD;
2172 6906 : nListenerCount++;
2173 13812 : }
2174 : }
2175 69352 : }
2176 :
2177 :
2178 : // Jetzt koennen noch SET-Methoden ohne zugehoerige GET-Methode existieren,
2179 : // diese muessen zu Write-Only-Properties gemachte werden.
2180 181156 : for( i = 0 ; i < nSourceMethodCount ; i++ )
2181 : {
2182 : // Methode ansprechen
2183 156590 : const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
2184 :
2185 : // Nur Methoden nehmen, die nicht schon zugeordnet sind
2186 156590 : if( pMethodTypes[i] != STANDARD_METHOD )
2187 102704 : continue;
2188 :
2189 : // Namen besorgen
2190 53886 : aMethName = rxMethod_i->getName();
2191 :
2192 : // Wenn der Name zu kurz ist, wird's sowieso nichts
2193 53886 : if( aMethName.getLength() <= 3 )
2194 30 : continue;
2195 :
2196 : // Ist es eine set-Methode ohne zugehoerige get-Methode?
2197 53856 : aStartStr = aMethName.copy( 0, 3 );
2198 53856 : if( aStartStr == "set" )
2199 : {
2200 : // Namen der potentiellen Property
2201 4516 : aPropName = aMethName.copy( 3 );
2202 :
2203 : // set-Methode muss void returnen
2204 4516 : Reference<XIdlClass> xSetRetType = rxMethod_i->getReturnType();
2205 4516 : if( xSetRetType->getTypeClass() != TypeClass_VOID )
2206 : {
2207 146 : continue;
2208 : }
2209 :
2210 : // set-Methode darf nur einen Parameter haben
2211 5664 : Sequence< Reference<XIdlClass> > setParams = rxMethod_i->getParameterTypes();
2212 4370 : sal_Int32 nParamCount = setParams.getLength();
2213 4370 : if( nParamCount != 1 )
2214 : {
2215 1972 : continue;
2216 : }
2217 :
2218 : // Haben wir den Namen schon?
2219 2398 : IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2220 2398 : if( !( aIt == rPropNameMap.end() ) )
2221 : {
2222 : /* TODO:
2223 : OSL_TRACE(
2224 : String( "Introspection: Property \"" ) +
2225 : OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2226 : String( "\" found more than once" ) );
2227 : */
2228 1104 : continue;
2229 : }
2230 :
2231 : // Alles klar, es ist eine Write-Only-Property
2232 1294 : pLocalMethodConcepts[ i ] = PROPERTY;
2233 :
2234 1294 : pMethodTypes[i] = GETSET_METHOD;
2235 2588 : Reference<XIdlClass> xGetRetType = setParams.getConstArray()[0];
2236 :
2237 : // Ist die PropertySequence gross genug?
2238 : pAccess->checkPropertyArraysSize
2239 1294 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2240 :
2241 : // In eigenes Property-Array eintragen
2242 1294 : Property& rProp = pAllPropArray[ rPropCount ];
2243 1294 : rProp.Name = aPropName;
2244 1294 : rProp.Handle = rPropCount;
2245 1294 : rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
2246 1294 : rProp.Attributes = 0; // PROPERTY_WRITEONLY ???
2247 :
2248 : // Neuer Eintrag in die Hashtable
2249 1294 : rPropNameMap[ aPropName ] = rPropCount;
2250 :
2251 : // Tabelle fuer XExactName pflegen
2252 1294 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2253 :
2254 : // set-Methode merken
2255 1294 : pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
2256 2588 : pInterfaces2, rPropCount );
2257 1294 : pInterfaces2[ rPropCount ] = rxMethod_i;
2258 :
2259 : // Art der Property merken
2260 1294 : pMapTypeArray[ rPropCount ] = MAP_SETONLY;
2261 1294 : pPropertyConceptArray[ rPropCount ] = METHODS;
2262 1294 : pAccess->mnMethodPropCount++;
2263 :
2264 : // Count pflegen
2265 2588 : rPropCount++;
2266 : }
2267 : }
2268 :
2269 :
2270 :
2271 :
2272 : // 4. Methoden in die Gesamt-Sequence uebernehmen
2273 :
2274 : // Wieviele Methoden muessen in die Method-Sequence?
2275 24566 : sal_Int32 nExportedMethodCount = 0;
2276 24566 : sal_Int32 nSupportedListenerCount = 0;
2277 181156 : for( i = 0 ; i < nSourceMethodCount ; i++ )
2278 : {
2279 156590 : if( pMethodTypes[ i ] != INVALID_METHOD )
2280 : {
2281 85382 : nExportedMethodCount++;
2282 : }
2283 156590 : if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
2284 : {
2285 6906 : nSupportedListenerCount++;
2286 : }
2287 : }
2288 :
2289 : // Sequences im Access-Objekt entsprechend aufbohren
2290 24566 : pAccess->maAllMethodSeq.realloc( nExportedMethodCount + iAllExportedMethod );
2291 24566 : pAccess->maMethodConceptSeq.realloc( nExportedMethodCount + iAllExportedMethod );
2292 24566 : pAccess->maSupportedListenerSeq.realloc( nSupportedListenerCount + iAllSupportedListener );
2293 :
2294 : // Methoden reinschreiben
2295 24566 : Reference<XIdlMethod>* pDestMethods = pAccess->maAllMethodSeq.getArray();
2296 24566 : sal_Int32* pMethodConceptArray = pAccess->maMethodConceptSeq.getArray();
2297 24566 : Type* pListenerClassRefs = pAccess->maSupportedListenerSeq.getArray();
2298 181156 : for( i = 0 ; i < nSourceMethodCount ; i++ )
2299 : {
2300 156590 : if( pMethodTypes[ i ] != INVALID_METHOD )
2301 : {
2302 : // Methode ansprechen
2303 85382 : const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
2304 :
2305 : // Namen in Hashtable eintragen, wenn nicht schon bekannt
2306 85382 : OUString aMethName2 = rxMethod->getName();
2307 85382 : IntrospectionNameMap::iterator aIt = rMethodNameMap.find( aMethName2 );
2308 85382 : if( aIt == rMethodNameMap.end() )
2309 : {
2310 : // Eintragen
2311 65744 : rMethodNameMap[ aMethName2 ] = iAllExportedMethod;
2312 :
2313 : // Tabelle fuer XExactName pflegen
2314 65744 : rLowerToExactNameMap[ toLower( aMethName2 ) ] = aMethName2;
2315 : }
2316 : else
2317 : {
2318 19638 : sal_Int32 iHashResult = (*aIt).second;
2319 :
2320 19638 : Reference<XIdlMethod> xExistingMethod = pDestMethods[ iHashResult ];
2321 :
2322 : Reference< XIdlClass > xExistingMethClass =
2323 21536 : xExistingMethod->getDeclaringClass();
2324 21536 : Reference< XIdlClass > xNewMethClass = rxMethod->getDeclaringClass();
2325 19638 : if( xExistingMethClass->equals( xNewMethClass ) )
2326 19638 : continue;
2327 : }
2328 :
2329 67642 : pDestMethods[ iAllExportedMethod ] = rxMethod;
2330 :
2331 : // Wenn kein Concept gesetzt wurde, ist die Methode "normal"
2332 67642 : sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
2333 67642 : if( !rMethodConcept_i )
2334 35858 : rMethodConcept_i = MethodConcept_NORMAL_IMPL;
2335 67642 : pMethodConceptArray[ iAllExportedMethod ] = rMethodConcept_i;
2336 67642 : iAllExportedMethod++;
2337 : }
2338 138850 : if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
2339 : {
2340 : // Klasse des Listeners ermitteln
2341 5280 : const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
2342 :
2343 : // void als Default-Klasse eintragen
2344 : css::uno::Reference<css::reflection::XIdlClass>
2345 : xListenerClass(
2346 5280 : reflection_->forName(
2347 5280 : cppu::UnoType<cppu::UnoVoidType>::get()
2348 10560 : .getTypeName()));
2349 : // ALT: Reference<XIdlClass> xListenerClass = Void_getReflection()->getIdlClass();
2350 :
2351 : // 1. Moeglichkeit: Parameter nach einer Listener-Klasse durchsuchen
2352 : // Nachteil: Superklassen muessen rekursiv durchsucht werden
2353 10560 : Sequence< Reference<XIdlClass> > aParams = rxMethod->getParameterTypes();
2354 5280 : const Reference<XIdlClass>* pParamArray2 = aParams.getConstArray();
2355 :
2356 : css::uno::Reference<css::reflection::XIdlClass>
2357 : xEventListenerClass(
2358 5280 : reflection_->forName(
2359 : cppu::UnoType<
2360 5280 : css::lang::XEventListener>::get()
2361 15840 : .getTypeName()));
2362 : // ALT: Reference<XIdlClass> xEventListenerClass = XEventListener_getReflection()->getIdlClass();
2363 5280 : sal_Int32 nParamCount = aParams.getLength();
2364 : sal_Int32 k;
2365 6458 : for( k = 0 ; k < nParamCount ; k++ )
2366 : {
2367 6456 : const Reference<XIdlClass>& rxClass = pParamArray2[k];
2368 :
2369 : // Sind wir von einem Listener abgeleitet?
2370 30076 : if( rxClass->equals( xEventListenerClass ) ||
2371 27872 : isDerivedFrom( rxClass, xEventListenerClass ) )
2372 : {
2373 5278 : xListenerClass = rxClass;
2374 5278 : break;
2375 : }
2376 : }
2377 :
2378 : // 2. Moeglichkeit: Namen der Methode auswerden
2379 : // Nachteil: geht nicht bei Test-Listenern, die es nicht gibt
2380 : //aMethName = rxMethod->getName();
2381 : //aListenerName = aMethName.Copy( 3, aMethName.Len()-8-3 );
2382 : //Reference<XIdlClass> xListenerClass = reflection->forName( aListenerName );
2383 10560 : Type aListenerType( TypeClass_INTERFACE, xListenerClass->getName() );
2384 5280 : pListenerClassRefs[ iAllSupportedListener ] = aListenerType;
2385 10560 : iAllSupportedListener++;
2386 : }
2387 : }
2388 :
2389 : // Wenn in diesem Durchlauf XInterface-Methoden
2390 : // dabei waren, diese zukuenftig ignorieren
2391 24566 : if( bFoundXInterface )
2392 24566 : bXInterfaceIsInvalid = true;
2393 :
2394 24566 : delete[] pMethodTypes;
2395 24566 : delete[] pLocalMethodConcepts;
2396 24566 : }
2397 :
2398 : // Super-Klasse(n) vorhanden? Dann dort fortsetzen
2399 100140 : Sequence< Reference<XIdlClass> > aSuperClassSeq = xImplClass2->getSuperclasses();
2400 :
2401 : // Zur Zeit wird nur von einer Superklasse ausgegangen
2402 50070 : if( aSuperClassSeq.getLength() >= 1 )
2403 : {
2404 27246 : xImplClass2 = aSuperClassSeq.getConstArray()[0];
2405 : OSL_ENSURE( xImplClass2.is(), "super class null" );
2406 : }
2407 : else
2408 : {
2409 22824 : xImplClass2 = NULL;
2410 : }
2411 50070 : }
2412 22824 : }
2413 :
2414 : // Anzahl der exportierten Methoden uebernehmen und Sequences anpassen
2415 : // (kann abweichen, weil doppelte Methoden erst nach der Ermittlung
2416 : // von nExportedMethodCount herausgeworfen werden)
2417 830 : sal_Int32& rMethCount = pAccess->mnMethCount;
2418 830 : rMethCount = iAllExportedMethod;
2419 830 : pAccess->maAllMethodSeq.realloc( rMethCount );
2420 830 : pAccess->maMethodConceptSeq.realloc( rMethCount );
2421 :
2422 : // Groesse der Property-Sequences anpassen
2423 830 : pAccess->maAllPropertySeq.realloc( rPropCount );
2424 830 : pAccess->maPropertyConceptSeq.realloc( rPropCount );
2425 830 : pAccess->maMapTypeSeq.realloc( rPropCount );
2426 : }
2427 : // Bei structs Fields als Properties registrieren
2428 : else //if( eType == TypeClass_STRUCT )
2429 : {
2430 : // Ist es ein Interface oder eine struct?
2431 : //Reference<XIdlClass> xClassRef = aToInspectObj.getReflection()->getIdlClass();
2432 : css::uno::Reference<css::reflection::XIdlClass> xClassRef(
2433 66 : reflection_->forName(aToInspectObj.getValueTypeName()));
2434 66 : if( !xClassRef.is() )
2435 : {
2436 : SAL_WARN( "stoc", "Can't get XIdlClass from Reflection" );
2437 0 : return new ImplIntrospectionAccess(aToInspectObj, pAccess);
2438 : }
2439 :
2440 : // Felder holen
2441 132 : Sequence< Reference<XIdlField> > fields = xClassRef->getFields();
2442 66 : const Reference<XIdlField>* pFields = fields.getConstArray();
2443 66 : sal_Int32 nLen = fields.getLength();
2444 :
2445 372 : for( i = 0 ; i < nLen ; i++ )
2446 : {
2447 306 : Reference<XIdlField> xField = pFields[i];
2448 612 : Reference<XIdlClass> xPropType = xField->getType();
2449 612 : OUString aPropName = xField->getName();
2450 :
2451 : // Ist die PropertySequence gross genug?
2452 : pAccess->checkPropertyArraysSize
2453 306 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2454 :
2455 : // In eigenes Property-Array eintragen
2456 306 : Property& rProp = pAllPropArray[ rPropCount ];
2457 306 : rProp.Name = aPropName;
2458 306 : rProp.Handle = rPropCount;
2459 306 : rProp.Type = Type( xPropType->getTypeClass(), xPropType->getName() );
2460 306 : FieldAccessMode eAccessMode = xField->getAccessMode();
2461 306 : rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
2462 : eAccessMode == FieldAccessMode_CONST)
2463 306 : ? READONLY : 0;
2464 :
2465 : //FieldAccessMode eAccessMode = xField->getAccessMode();
2466 : //rProp.Attributes = (eAccessMode == FieldAccessMode::READONLY || eAccessMode == CONST)
2467 : //? PropertyAttribute::READONLY : 0;
2468 :
2469 : // Namen in Hashtable eintragen
2470 306 : rPropNameMap[ aPropName ] = rPropCount;
2471 :
2472 : // Tabelle fuer XExactName pflegen
2473 306 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2474 :
2475 : // Field merken
2476 306 : pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
2477 612 : pInterfaces1, rPropCount );
2478 306 : pInterfaces1[ rPropCount ] = xField;
2479 :
2480 : // Art der Property merken
2481 306 : pMapTypeArray[ rPropCount ] = MAP_FIELD;
2482 306 : pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
2483 306 : pAccess->mnAttributePropCount++;
2484 :
2485 : // Count pflegen
2486 306 : rPropCount++;
2487 372 : }
2488 : }
2489 :
2490 : // Property-Sequence auf die richtige Laenge bringen
2491 896 : pAccess->maAllPropertySeq.realloc( pAccess->mnPropCount );
2492 :
2493 33628 : return new ImplIntrospectionAccess(aToInspectObj, pAccess);
2494 : }
2495 :
2496 178 : struct Instance {
2497 178 : explicit Instance(
2498 : css::uno::Reference<css::uno::XComponentContext> const & context):
2499 178 : instance(new Implementation(context))
2500 178 : {}
2501 :
2502 : rtl::Reference<cppu::OWeakObject> instance;
2503 : };
2504 :
2505 : struct Singleton:
2506 : public rtl::StaticWithArg<
2507 : Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton>
2508 : {};
2509 :
2510 : }
2511 :
2512 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
2513 180 : com_sun_star_comp_stoc_Introspection_get_implementation(
2514 : css::uno::XComponentContext * context,
2515 : css::uno::Sequence<css::uno::Any> const & arguments)
2516 : {
2517 : SAL_WARN_IF(
2518 : arguments.hasElements(), "stoc", "unexpected singleton arguments");
2519 180 : return cppu::acquire(Singleton::get(context).instance.get());
2520 : }
2521 :
2522 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|