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