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 <string.h>
21 :
22 : #define INTROSPECTION_CACHE_MAX_SIZE 100
23 :
24 : #include <osl/diagnose.h>
25 : #include <osl/mutex.hxx>
26 : #include <osl/thread.h>
27 : #include <cppuhelper/queryinterface.hxx>
28 : #include <cppuhelper/weak.hxx>
29 : #include <cppuhelper/component.hxx>
30 : #include <cppuhelper/factory.hxx>
31 : #include <cppuhelper/implbase3.hxx>
32 : #include <cppuhelper/typeprovider.hxx>
33 : #include <salhelper/simplereferenceobject.hxx>
34 :
35 : #include <com/sun/star/uno/DeploymentException.hpp>
36 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
37 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 : #include <com/sun/star/lang/XServiceInfo.hpp>
39 : #include <com/sun/star/lang/XEventListener.hpp>
40 : #include <com/sun/star/reflection/XIdlReflection.hpp>
41 : #include <com/sun/star/reflection/XIdlClass.hpp>
42 : #include <com/sun/star/reflection/XIdlField2.hpp>
43 : #include <com/sun/star/beans/UnknownPropertyException.hpp>
44 : #include <com/sun/star/beans/Property.hpp>
45 : #include <com/sun/star/beans/XPropertySet.hpp>
46 : #include <com/sun/star/beans/XFastPropertySet.hpp>
47 : #include <com/sun/star/beans/XIntrospection.hpp>
48 : #include <com/sun/star/beans/XIntrospectionAccess.hpp>
49 : #include <com/sun/star/beans/XMaterialHolder.hpp>
50 : #include <com/sun/star/beans/XExactName.hpp>
51 : #include <com/sun/star/beans/PropertyAttribute.hpp>
52 : #include <com/sun/star/beans/PropertyConcept.hpp>
53 : #include <com/sun/star/beans/MethodConcept.hpp>
54 : #include <com/sun/star/container/XNameContainer.hpp>
55 : #include <com/sun/star/container/XIndexContainer.hpp>
56 : #include <com/sun/star/container/XEnumerationAccess.hpp>
57 :
58 : #include <rtl/ref.hxx>
59 : #include <rtl/ustrbuf.hxx>
60 : #include <rtl/strbuf.hxx>
61 : #include <boost/unordered_map.hpp>
62 :
63 : using namespace com::sun::star::uno;
64 : using namespace com::sun::star::lang;
65 : using namespace com::sun::star::reflection;
66 : using namespace com::sun::star::container;
67 : using namespace com::sun::star::registry;
68 : using namespace com::sun::star::beans;
69 : using namespace com::sun::star::beans::PropertyAttribute;
70 : using namespace com::sun::star::beans::PropertyConcept;
71 : using namespace com::sun::star::beans::MethodConcept;
72 : using namespace cppu;
73 : using namespace osl;
74 :
75 : #define IMPLEMENTATION_NAME "com.sun.star.comp.stoc.Introspection"
76 : #define SERVICE_NAME "com.sun.star.beans.Introspection"
77 :
78 : namespace stoc_inspect
79 : {
80 :
81 : typedef WeakImplHelper3< XIntrospectionAccess, XMaterialHolder, XExactName > IntrospectionAccessHelper;
82 :
83 :
84 : //==================================================================================================
85 :
86 : // Special value for Method-Concept, to be able to mark "normal" functions
87 : #define MethodConcept_NORMAL_IMPL 0x80000000
88 :
89 :
90 : // Method to assert, if a class is derived from another class
91 2185 : sal_Bool isDerivedFrom( Reference<XIdlClass> xToTestClass, Reference<XIdlClass> xDerivedFromClass )
92 : {
93 2185 : Sequence< Reference<XIdlClass> > aClassesSeq = xToTestClass->getSuperclasses();
94 2185 : const Reference<XIdlClass>* pClassesArray = aClassesSeq.getConstArray();
95 :
96 2185 : sal_Int32 nSuperClassCount = aClassesSeq.getLength();
97 2186 : for ( sal_Int32 i = 0; i < nSuperClassCount; ++i )
98 : {
99 1667 : const Reference<XIdlClass>& rxClass = pClassesArray[i];
100 :
101 5003 : if ( xDerivedFromClass->equals( rxClass ) ||
102 1671 : isDerivedFrom( rxClass, xDerivedFromClass )
103 : )
104 1666 : return sal_True;
105 : }
106 :
107 519 : return sal_False;
108 : }
109 :
110 : //========================================================================
111 :
112 : // *** Classification of Properties (no enum, to be able to use Sequence) ***
113 : // Properties from a PropertySet-Interface
114 : #define MAP_PROPERTY_SET 0
115 : // Properties from Fields
116 : #define MAP_FIELD 1
117 : // Properties, that get described with get/set-Methods
118 : #define MAP_GETSET 2
119 : // Properties, with only a set-Method
120 : #define MAP_SETONLY 3
121 :
122 :
123 : // Increments, in which the size of Sequences get adjusted
124 : #define ARRAY_SIZE_STEP 20
125 :
126 :
127 :
128 : //**************************************
129 : //*** IntrospectionAccessStatic_Impl ***
130 : //**************************************
131 : // Equals to the old IntrospectionAccessImpl, forms now a static
132 : // part of the new Instance-related ImplIntrospectionAccess
133 :
134 : // Hashtable for the search of names
135 : struct hashName_Impl
136 : {
137 150506 : size_t operator()(const OUString Str) const
138 : {
139 150506 : return (size_t)Str.hashCode();
140 : }
141 : };
142 :
143 : struct eqName_Impl
144 : {
145 19547 : sal_Bool operator()(const OUString Str1, const OUString Str2) const
146 : {
147 19547 : return ( Str1 == Str2 );
148 : }
149 : };
150 :
151 : typedef boost::unordered_map
152 : <
153 : OUString,
154 : sal_Int32,
155 : hashName_Impl,
156 : eqName_Impl
157 : >
158 : IntrospectionNameMap;
159 :
160 :
161 : // Hashtable to assign exact names to the Lower-Case
162 : // converted names, for the support of XExactName
163 : typedef boost::unordered_map
164 : <
165 : OUString,
166 : OUString,
167 : hashName_Impl,
168 : eqName_Impl
169 : >
170 : LowerToExactNameMap;
171 :
172 :
173 : class ImplIntrospectionAccess;
174 : class IntrospectionAccessStatic_Impl: public salhelper::SimpleReferenceObject
175 : {
176 : friend class ImplIntrospection;
177 : friend class ImplIntrospectionAccess;
178 :
179 : // Holding CoreReflection
180 : Reference< XIdlReflection > mxCoreReflection;
181 :
182 : // InterfaceSequences, to save additional information in a property
183 : // for example the Field at MAP_FIELD, the get/set-Methods at MAP_GETSET, et cetera
184 : Sequence< Reference<XInterface> > aInterfaceSeq1;
185 : Sequence< Reference<XInterface> > aInterfaceSeq2;
186 :
187 : // Hashtables for names
188 : IntrospectionNameMap maPropertyNameMap;
189 : IntrospectionNameMap maMethodNameMap;
190 : LowerToExactNameMap maLowerToExactNameMap;
191 :
192 : // Sequence of all Properties, also for delivering from getProperties()
193 : Sequence<Property> maAllPropertySeq;
194 :
195 : // Mapping of properties to Access-Types
196 : Sequence<sal_Int16> maMapTypeSeq;
197 :
198 : // Classification of found methods
199 : Sequence<sal_Int32> maPropertyConceptSeq;
200 :
201 : // Number of Properties
202 : sal_Int32 mnPropCount;
203 :
204 : // Number of Properties, which are assigned to particular concepts
205 : //sal_Int32 mnDangerousPropCount;
206 : sal_Int32 mnPropertySetPropCount;
207 : sal_Int32 mnAttributePropCount;
208 : sal_Int32 mnMethodPropCount;
209 :
210 : // Flag, if a FastPropertySet is supported
211 : sal_Bool mbFastPropSet;
212 :
213 : // Original-Handles of FastPropertySets
214 : sal_Int32* mpOrgPropertyHandleArray;
215 :
216 : // MethodSequence, that accepts all methods
217 : Sequence< Reference<XIdlMethod> > maAllMethodSeq;
218 :
219 : // Classification of found methods
220 : Sequence<sal_Int32> maMethodConceptSeq;
221 :
222 : // Number of methods
223 : sal_Int32 mnMethCount;
224 :
225 : // Sequence of Listener, that can be registered
226 : Sequence< Type > maSupportedListenerSeq;
227 :
228 : // BaseInit (should be done later in the application!)
229 : void BaseInit( void );
230 :
231 : // Helper-methods for adjusting sizes of Sequences
232 : void checkPropertyArraysSize
233 : (
234 : Property*& rpAllPropArray,
235 : sal_Int16*& rpMapTypeArray,
236 : sal_Int32*& rpPropertyConceptArray,
237 : sal_Int32 iNextIndex
238 : );
239 : void checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq, Reference<XInterface>*& rpInterfaceArray,
240 : sal_Int32 iNextIndex );
241 :
242 : public:
243 : IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ );
244 562 : ~IntrospectionAccessStatic_Impl()
245 562 : {
246 281 : delete[] mpOrgPropertyHandleArray;
247 562 : }
248 : sal_Int32 getPropertyIndex( const OUString& aPropertyName ) const;
249 : sal_Int32 getMethodIndex( const OUString& aMethodName ) const;
250 :
251 : // Methods of XIntrospectionAccess (OLD, now only Impl)
252 : void setPropertyValue(const Any& obj, const OUString& aPropertyName, const Any& aValue) const;
253 : // void setPropertyValue(Any& obj, const OUString& aPropertyName, const Any& aValue) const;
254 : Any getPropertyValue(const Any& obj, const OUString& aPropertyName) const;
255 : void setPropertyValueByIndex(const Any& obj, sal_Int32 nIndex, const Any& aValue) const;
256 : // void setPropertyValueByIndex(Any& obj, sal_Int32 nIndex, const Any& aValue) const;
257 : Any getPropertyValueByIndex(const Any& obj, sal_Int32 nIndex) const;
258 :
259 1283 : Sequence<Property> getProperties(void) const { return maAllPropertySeq; }
260 1385 : Sequence< Reference<XIdlMethod> > getMethods(void) const { return maAllMethodSeq; }
261 9 : Sequence< Type > getSupportedListeners(void) const { return maSupportedListenerSeq; }
262 2570 : Sequence<sal_Int32> getPropertyConcepts(void) const { return maPropertyConceptSeq; }
263 2534 : Sequence<sal_Int32> getMethodConcepts(void) const { return maMethodConceptSeq; }
264 : };
265 :
266 :
267 : // Ctor
268 360 : IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ )
269 360 : : mxCoreReflection( xCoreReflection_ )
270 : {
271 360 : aInterfaceSeq1.realloc( ARRAY_SIZE_STEP );
272 360 : aInterfaceSeq2.realloc( ARRAY_SIZE_STEP );
273 :
274 : // Property-Data
275 360 : maAllPropertySeq.realloc( ARRAY_SIZE_STEP );
276 360 : maMapTypeSeq.realloc( ARRAY_SIZE_STEP );
277 360 : maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP );
278 :
279 360 : mbFastPropSet = sal_False;
280 360 : mpOrgPropertyHandleArray = NULL;
281 :
282 360 : mnPropCount = 0;
283 : //mnDangerousPropCount = 0;
284 360 : mnPropertySetPropCount = 0;
285 360 : mnAttributePropCount = 0;
286 360 : mnMethodPropCount = 0;
287 :
288 : // Method-Data
289 360 : mnMethCount = 0;
290 360 : }
291 :
292 5813 : sal_Int32 IntrospectionAccessStatic_Impl::getPropertyIndex( const OUString& aPropertyName ) const
293 : {
294 5813 : sal_Int32 iHashResult = -1;
295 5813 : IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
296 5813 : IntrospectionNameMap::iterator aIt = pThis->maPropertyNameMap.find( aPropertyName );
297 5813 : if( !( aIt == pThis->maPropertyNameMap.end() ) )
298 4633 : iHashResult = (*aIt).second;
299 5813 : return iHashResult;
300 : }
301 :
302 2509 : sal_Int32 IntrospectionAccessStatic_Impl::getMethodIndex( const OUString& aMethodName ) const
303 : {
304 2509 : sal_Int32 iHashResult = -1;
305 2509 : IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
306 2509 : IntrospectionNameMap::iterator aIt = pThis->maMethodNameMap.find( aMethodName );
307 2509 : if( !( aIt == pThis->maMethodNameMap.end() ) )
308 : {
309 2342 : iHashResult = (*aIt).second;
310 : }
311 : // #95159 Check if full qualified name matches
312 : else
313 : {
314 167 : sal_Int32 nSearchFrom = aMethodName.getLength();
315 : while( true )
316 : {
317 : // Strategy: Search back until the first '_' is found
318 171 : sal_Int32 nFound = aMethodName.lastIndexOf( '_', nSearchFrom );
319 171 : if( nFound == -1 )
320 334 : break;
321 :
322 4 : OUString aPureMethodName = aMethodName.copy( nFound + 1 );
323 :
324 4 : aIt = pThis->maMethodNameMap.find( aPureMethodName );
325 4 : if( !( aIt == pThis->maMethodNameMap.end() ) )
326 : {
327 : // Check if it can be a type?
328 : // Problem: Does not work if package names contain _ ?!
329 0 : OUString aStr = aMethodName.copy( 0, nFound );
330 0 : OUString aTypeName = aStr.replace( '_', '.' );
331 0 : Reference< XIdlClass > xClass = mxCoreReflection->forName( aTypeName );
332 0 : if( xClass.is() )
333 : {
334 : // If this is a valid class it could be the right method
335 :
336 : // Could be the right method, type has to be checked
337 0 : iHashResult = (*aIt).second;
338 :
339 0 : const Reference<XIdlMethod>* pMethods = maAllMethodSeq.getConstArray();
340 0 : const Reference<XIdlMethod> xMethod = pMethods[ iHashResult ];
341 :
342 0 : Reference< XIdlClass > xMethClass = xMethod->getDeclaringClass();
343 0 : if( xClass->equals( xMethClass ) )
344 : {
345 0 : break;
346 : }
347 : else
348 : {
349 0 : iHashResult = -1;
350 :
351 : // Could also be another method with the same name
352 : // Iterate over all methods
353 0 : sal_Int32 nLen = maAllMethodSeq.getLength();
354 0 : for( int i = 0 ; i < nLen ; ++i )
355 : {
356 0 : const Reference<XIdlMethod> xMethod2 = pMethods[ i ];
357 0 : if( xMethod2->getName() == aPureMethodName )
358 : {
359 0 : Reference< XIdlClass > xMethClass2 = xMethod2->getDeclaringClass();
360 :
361 0 : if( xClass->equals( xMethClass2 ) )
362 : {
363 0 : iHashResult = i;
364 0 : break;
365 0 : }
366 : }
367 0 : }
368 :
369 0 : if( iHashResult != -1 )
370 0 : break;
371 0 : }
372 0 : }
373 : }
374 :
375 4 : nSearchFrom = nFound - 1;
376 4 : if( nSearchFrom < 0 )
377 0 : break;
378 4 : }
379 : }
380 2509 : return iHashResult;
381 : }
382 :
383 558 : void IntrospectionAccessStatic_Impl::setPropertyValue( const Any& obj, const OUString& aPropertyName, const Any& aValue ) const
384 : //void IntrospectionAccessStatic_Impl::setPropertyValue( Any& obj, const OUString& aPropertyName, const Any& aValue ) const
385 : {
386 558 : sal_Int32 i = getPropertyIndex( aPropertyName );
387 558 : if( i != -1 )
388 558 : setPropertyValueByIndex( obj, (sal_Int32)i, aValue );
389 : else
390 0 : throw UnknownPropertyException();
391 558 : }
392 :
393 558 : void IntrospectionAccessStatic_Impl::setPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
394 : //void IntrospectionAccessStatic_Impl::setPropertyValueByIndex( Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
395 : {
396 : // Is the passed object something that fits?
397 558 : TypeClass eObjType = obj.getValueType().getTypeClass();
398 :
399 558 : Reference<XInterface> xInterface;
400 558 : if( eObjType == TypeClass_INTERFACE )
401 : {
402 506 : xInterface = *( Reference<XInterface>*)obj.getValue();
403 : }
404 52 : else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
405 : {
406 0 : throw IllegalArgumentException();
407 : }
408 :
409 : // Test flags
410 558 : const Property* pProps = maAllPropertySeq.getConstArray();
411 558 : if( (pProps[ nSequenceIndex ].Attributes & READONLY) != 0 )
412 : {
413 0 : throw UnknownPropertyException();
414 : }
415 :
416 558 : const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
417 558 : switch( pMapTypeArray[ nSequenceIndex ] )
418 : {
419 : case MAP_PROPERTY_SET:
420 : {
421 : // Get Property
422 3 : const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
423 :
424 : // Convert Interface-Parameter to the correct type
425 3 : sal_Bool bUseCopy = sal_False;
426 3 : Any aRealValue;
427 :
428 3 : TypeClass eValType = aValue.getValueType().getTypeClass();
429 3 : if( eValType == TypeClass_INTERFACE )
430 : {
431 1 : Type aPropType = rProp.Type;
432 2 : OUString aTypeName( aPropType.getTypeName() );
433 2 : Reference< XIdlClass > xPropClass = mxCoreReflection->forName( aTypeName );
434 : //Reference<XIdlClass> xPropClass = rProp.Type;
435 1 : if( xPropClass.is() && xPropClass->getTypeClass() == TypeClass_INTERFACE )
436 : {
437 1 : Reference<XInterface> valInterface = *(Reference<XInterface>*)aValue.getValue();
438 1 : if( valInterface.is() )
439 : {
440 : //Any queryInterface( const Type& rType );
441 1 : aRealValue = valInterface->queryInterface( aPropType );
442 1 : if( aRealValue.hasValue() )
443 1 : bUseCopy = sal_True;
444 1 : }
445 1 : }
446 : }
447 :
448 : // Do we have a FastPropertySet and a valid Handle?
449 : // CAUTION: At this point we exploit, that the PropertySet
450 : // gets queried at the beginning of the Introspection-Process.
451 : sal_Int32 nOrgHandle;
452 3 : if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
453 : {
454 : // Retrieve PropertySet-Interface
455 : Reference<XFastPropertySet> xFastPropSet =
456 3 : Reference<XFastPropertySet>::query( xInterface );
457 3 : if( xFastPropSet.is() )
458 : {
459 3 : xFastPropSet->setFastPropertyValue( nOrgHandle, bUseCopy ? aRealValue : aValue );
460 : }
461 : else
462 : {
463 : // throw UnknownPropertyException
464 3 : }
465 : }
466 : // else take the normal one
467 : else
468 : {
469 : // Retrieve PropertySet-Interface
470 : Reference<XPropertySet> xPropSet =
471 0 : Reference<XPropertySet>::query( xInterface );
472 0 : if( xPropSet.is() )
473 : {
474 0 : xPropSet->setPropertyValue( rProp.Name, bUseCopy ? aRealValue : aValue );
475 : }
476 : else
477 : {
478 : // throw UnknownPropertyException
479 0 : }
480 3 : }
481 : }
482 3 : break;
483 :
484 : case MAP_FIELD:
485 : {
486 516 : Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
487 1032 : Reference<XIdlField2> xField2(xField, UNO_QUERY);
488 516 : if( xField2.is() )
489 : {
490 516 : xField2->set( (Any&)obj, aValue );
491 : // IllegalArgumentException
492 : // NullPointerException
493 : } else
494 0 : if( xField.is() )
495 : {
496 0 : xField->set( obj, aValue );
497 : // IllegalArgumentException
498 : // NullPointerException
499 : }
500 : else
501 : {
502 : // throw IllegalArgumentException();
503 516 : }
504 : }
505 516 : break;
506 :
507 : case MAP_GETSET:
508 : case MAP_SETONLY:
509 : {
510 : // Retrieve set-Methods
511 39 : Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq2.getConstArray()[ nSequenceIndex ].get());
512 39 : if( xMethod.is() )
513 : {
514 39 : Sequence<Any> args( 1 );
515 39 : args.getArray()[0] = aValue;
516 39 : xMethod->invoke( obj, args );
517 : }
518 : else
519 : {
520 : // throw IllegalArgumentException();
521 39 : }
522 : }
523 39 : break;
524 558 : }
525 558 : }
526 :
527 1505 : Any IntrospectionAccessStatic_Impl::getPropertyValue( const Any& obj, const OUString& aPropertyName ) const
528 : {
529 1505 : sal_Int32 i = getPropertyIndex( aPropertyName );
530 1505 : if( i != -1 )
531 3010 : return getPropertyValueByIndex( obj, i );
532 :
533 0 : throw UnknownPropertyException();
534 : }
535 :
536 1505 : Any IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex) const
537 : {
538 1505 : Any aRet;
539 :
540 : // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes?
541 1505 : TypeClass eObjType = obj.getValueType().getTypeClass();
542 :
543 3010 : Reference<XInterface> xInterface;
544 1505 : if( eObjType == TypeClass_INTERFACE )
545 : {
546 1505 : xInterface = *(Reference<XInterface>*)obj.getValue();
547 : }
548 0 : else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
549 : {
550 : // throw IllegalArgumentException();
551 0 : return aRet;
552 : }
553 :
554 1505 : const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
555 1505 : switch( pMapTypeArray[ nSequenceIndex ] )
556 : {
557 : case MAP_PROPERTY_SET:
558 : {
559 : // Property besorgen
560 3 : const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
561 :
562 : // Haben wir ein FastPropertySet und ein gueltiges Handle?
563 : // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet
564 : // zu Beginn des Introspection-Vorgangs abgefragt wird.
565 : sal_Int32 nOrgHandle;
566 3 : if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
567 : {
568 : // PropertySet-Interface holen
569 : Reference<XFastPropertySet> xFastPropSet =
570 3 : Reference<XFastPropertySet>::query( xInterface );
571 3 : if( xFastPropSet.is() )
572 : {
573 3 : aRet = xFastPropSet->getFastPropertyValue( nOrgHandle);
574 : }
575 : else
576 : {
577 : // throw UnknownPropertyException
578 0 : return aRet;
579 3 : }
580 : }
581 : // sonst eben das normale nehmen
582 : else
583 : {
584 : // PropertySet-Interface holen
585 : Reference<XPropertySet> xPropSet =
586 0 : Reference<XPropertySet>::query( xInterface );
587 0 : if( xPropSet.is() )
588 : {
589 0 : aRet = xPropSet->getPropertyValue( rProp.Name );
590 : }
591 : else
592 : {
593 : // throw UnknownPropertyException
594 0 : return aRet;
595 0 : }
596 : }
597 : }
598 3 : break;
599 :
600 : case MAP_FIELD:
601 : {
602 1259 : Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
603 1259 : if( xField.is() )
604 : {
605 1259 : aRet = xField->get( obj );
606 : // IllegalArgumentException
607 : // NullPointerException
608 : }
609 : else
610 : {
611 : // throw IllegalArgumentException();
612 0 : return aRet;
613 1259 : }
614 : }
615 1259 : break;
616 :
617 : case MAP_GETSET:
618 : {
619 : // get-Methode holen
620 243 : Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
621 243 : if( xMethod.is() )
622 : {
623 243 : Sequence<Any> args;
624 243 : aRet = xMethod->invoke( obj, args );
625 : }
626 : else
627 : {
628 : // throw IllegalArgumentException();
629 0 : return aRet;
630 243 : }
631 : }
632 243 : break;
633 :
634 : case MAP_SETONLY:
635 : // get-Methode gibt es nicht
636 : // throw WriteOnlyPropertyException();
637 0 : return aRet;
638 : }
639 1505 : return aRet;
640 : }
641 :
642 :
643 : // Hilfs-Methoden zur Groessen-Anpassung der Sequences
644 18116 : void IntrospectionAccessStatic_Impl::checkPropertyArraysSize
645 : (
646 : Property*& rpAllPropArray,
647 : sal_Int16*& rpMapTypeArray,
648 : sal_Int32*& rpPropertyConceptArray,
649 : sal_Int32 iNextIndex
650 : )
651 : {
652 18116 : sal_Int32 nLen = maAllPropertySeq.getLength();
653 18116 : if( iNextIndex >= nLen )
654 : {
655 723 : maAllPropertySeq.realloc( nLen + ARRAY_SIZE_STEP );
656 723 : rpAllPropArray = maAllPropertySeq.getArray();
657 :
658 723 : maMapTypeSeq.realloc( nLen + ARRAY_SIZE_STEP );
659 723 : rpMapTypeArray = maMapTypeSeq.getArray();
660 :
661 723 : maPropertyConceptSeq.realloc( nLen + ARRAY_SIZE_STEP );
662 723 : rpPropertyConceptArray = maPropertyConceptSeq.getArray();
663 : }
664 18116 : }
665 :
666 8711 : void IntrospectionAccessStatic_Impl::checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq,
667 : Reference<XInterface>*& rpInterfaceArray, sal_Int32 iNextIndex )
668 : {
669 8711 : sal_Int32 nLen = rSeq.getLength();
670 8711 : if( iNextIndex >= nLen )
671 : {
672 : // Neue Groesse mit ARRAY_SIZE_STEP abgleichen
673 901 : sal_Int32 nMissingSize = iNextIndex - nLen + 1;
674 901 : sal_Int32 nSteps = nMissingSize / ARRAY_SIZE_STEP + 1;
675 901 : sal_Int32 nNewSize = nLen + nSteps * ARRAY_SIZE_STEP;
676 :
677 901 : rSeq.realloc( nNewSize );
678 901 : rpInterfaceArray = rSeq.getArray();
679 : }
680 8711 : }
681 :
682 :
683 : //*******************************
684 : //*** ImplIntrospectionAccess ***
685 : //*******************************
686 :
687 : // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
688 : // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
689 : // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
690 : class ImplIntrospectionAccess : public IntrospectionAccessHelper
691 : {
692 : friend class ImplIntrospection;
693 :
694 : // Untersuchtes Objekt
695 : Any maInspectedObject;
696 :
697 : // Als Interface
698 : Reference<XInterface> mxIface;
699 :
700 : // Statische Daten der Introspection
701 : rtl::Reference< IntrospectionAccessStatic_Impl > mpStaticImpl;
702 :
703 : // Adapter-Implementation
704 : WeakReference< XInterface > maAdapter;
705 :
706 : // Letzte Sequence, die bei getProperties geliefert wurde (Optimierung)
707 : Sequence<Property> maLastPropertySeq;
708 : sal_Int32 mnLastPropertyConcept;
709 :
710 : // Letzte Sequence, die bei getMethods geliefert wurde (Optimierung)
711 : Sequence<Reference<XIdlMethod> > maLastMethodSeq;
712 : sal_Int32 mnLastMethodConcept;
713 :
714 : public:
715 : ImplIntrospectionAccess( const Any& obj, rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ );
716 : ~ImplIntrospectionAccess();
717 :
718 : // Methoden von XIntrospectionAccess
719 : virtual sal_Int32 SAL_CALL getSuppliedMethodConcepts(void)
720 : throw( RuntimeException );
721 : virtual sal_Int32 SAL_CALL getSuppliedPropertyConcepts(void)
722 : throw( RuntimeException );
723 : virtual Property SAL_CALL getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
724 : throw( NoSuchElementException, RuntimeException );
725 : virtual sal_Bool SAL_CALL hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
726 : throw( RuntimeException );
727 : virtual Sequence< Property > SAL_CALL getProperties(sal_Int32 PropertyConcepts)
728 : throw( RuntimeException );
729 : virtual Reference<XIdlMethod> SAL_CALL getMethod(const OUString& Name, sal_Int32 MethodConcepts)
730 : throw( NoSuchMethodException, RuntimeException );
731 : virtual sal_Bool SAL_CALL hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
732 : throw( RuntimeException );
733 : virtual Sequence< Reference<XIdlMethod> > SAL_CALL getMethods(sal_Int32 MethodConcepts)
734 : throw( RuntimeException );
735 : virtual Sequence< Type > SAL_CALL getSupportedListeners(void)
736 : throw( RuntimeException );
737 : using OWeakObject::queryAdapter;
738 : virtual Reference<XInterface> SAL_CALL queryAdapter( const Type& rType )
739 : throw( IllegalTypeException, RuntimeException );
740 :
741 : // Methoden von XMaterialHolder
742 : virtual Any SAL_CALL getMaterial(void) throw(RuntimeException);
743 :
744 : // Methoden von XExactName
745 : virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) throw( RuntimeException );
746 : };
747 :
748 3792 : ImplIntrospectionAccess::ImplIntrospectionAccess
749 : ( const Any& obj, rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ )
750 3792 : : maInspectedObject( obj ), mpStaticImpl( pStaticImpl_ ), maAdapter()
751 : {
752 : // Objekt als Interface merken, wenn moeglich
753 3792 : TypeClass eType = maInspectedObject.getValueType().getTypeClass();
754 3792 : if( eType == TypeClass_INTERFACE )
755 3551 : mxIface = *(Reference<XInterface>*)maInspectedObject.getValue();
756 :
757 3792 : mnLastPropertyConcept = -1;
758 3792 : mnLastMethodConcept = -1;
759 3792 : }
760 :
761 7176 : ImplIntrospectionAccess::~ImplIntrospectionAccess()
762 : {
763 7176 : }
764 :
765 :
766 : //*******************************
767 : //*** ImplIntrospectionAdapter ***
768 : //*******************************
769 :
770 : // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
771 : // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
772 : // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
773 5474 : class ImplIntrospectionAdapter :
774 : public XPropertySet, public XFastPropertySet, public XPropertySetInfo,
775 : public XNameContainer, public XIndexContainer,
776 : public XEnumerationAccess, public XIdlArray,
777 : public OWeakObject
778 : {
779 : // Parent-Objekt
780 : ::rtl::Reference< ImplIntrospectionAccess > mpAccess;
781 :
782 : // Untersuchtes Objekt
783 : const Any& mrInspectedObject;
784 :
785 : // Statische Daten der Introspection
786 : rtl::Reference< IntrospectionAccessStatic_Impl > mpStaticImpl;
787 :
788 : // Objekt als Interface
789 : Reference<XInterface> mxIface;
790 :
791 : // Original-Interfaces des Objekts
792 : Reference<XElementAccess> mxObjElementAccess;
793 : Reference<XNameContainer> mxObjNameContainer;
794 : Reference<XNameAccess> mxObjNameAccess;
795 : Reference<XIndexAccess> mxObjIndexAccess;
796 : Reference<XIndexContainer> mxObjIndexContainer;
797 : Reference<XEnumerationAccess> mxObjEnumerationAccess;
798 : Reference<XIdlArray> mxObjIdlArray;
799 :
800 : public:
801 : ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
802 : const Any& obj,
803 : rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ );
804 :
805 : // Methoden von XInterface
806 : virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
807 21608 : virtual void SAL_CALL acquire() throw() { OWeakObject::acquire(); }
808 21562 : virtual void SAL_CALL release() throw() { OWeakObject::release(); }
809 :
810 : // Methoden von XPropertySet
811 : virtual Reference<XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( RuntimeException );
812 : virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName, const Any& aValue)
813 : throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException );
814 : virtual Any SAL_CALL getPropertyValue(const OUString& aPropertyName)
815 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
816 : virtual void SAL_CALL addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
817 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
818 : virtual void SAL_CALL removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
819 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
820 : virtual void SAL_CALL addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
821 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
822 : virtual void SAL_CALL removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
823 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
824 :
825 : // Methoden von XFastPropertySet
826 : virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const Any& aValue)
827 : throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException );
828 : virtual Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle)
829 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
830 :
831 : // Methoden von XPropertySetInfo
832 : virtual Sequence< Property > SAL_CALL getProperties(void) throw( RuntimeException );
833 : virtual Property SAL_CALL getPropertyByName(const OUString& Name) throw( RuntimeException );
834 : virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& Name) throw( RuntimeException );
835 :
836 : // Methoden von XElementAccess
837 : virtual Type SAL_CALL getElementType(void) throw( RuntimeException );
838 : virtual sal_Bool SAL_CALL hasElements(void) throw( RuntimeException );
839 :
840 : // Methoden von XNameAccess
841 : virtual Any SAL_CALL getByName(const OUString& Name)
842 : throw( NoSuchElementException, WrappedTargetException, RuntimeException );
843 : virtual Sequence< OUString > SAL_CALL getElementNames(void) throw( RuntimeException );
844 : virtual sal_Bool SAL_CALL hasByName(const OUString& Name) throw( RuntimeException );
845 :
846 : // Methoden von XNameContainer
847 : virtual void SAL_CALL insertByName(const OUString& Name, const Any& Element)
848 : throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException );
849 : virtual void SAL_CALL replaceByName(const OUString& Name, const Any& Element)
850 : throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException );
851 : virtual void SAL_CALL removeByName(const OUString& Name)
852 : throw( NoSuchElementException, WrappedTargetException, RuntimeException );
853 :
854 : // Methoden von XIndexAccess
855 : virtual sal_Int32 SAL_CALL getCount(void) throw( RuntimeException );
856 : virtual Any SAL_CALL getByIndex(sal_Int32 Index)
857 : throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
858 :
859 : // Methoden von XIndexContainer
860 : virtual void SAL_CALL insertByIndex(sal_Int32 Index, const Any& Element)
861 : throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
862 : virtual void SAL_CALL replaceByIndex(sal_Int32 Index, const Any& Element)
863 : throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
864 : virtual void SAL_CALL removeByIndex(sal_Int32 Index)
865 : throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
866 :
867 : // Methoden von XEnumerationAccess
868 : virtual Reference<XEnumeration> SAL_CALL createEnumeration(void) throw( RuntimeException );
869 :
870 : // Methoden von XIdlArray
871 : virtual void SAL_CALL realloc(Any& array, sal_Int32 length)
872 : throw( IllegalArgumentException, RuntimeException );
873 : virtual sal_Int32 SAL_CALL getLen(const Any& array) throw( IllegalArgumentException, RuntimeException );
874 : virtual Any SAL_CALL get(const Any& array, sal_Int32 index)
875 : throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException );
876 : virtual void SAL_CALL set(Any& array, sal_Int32 index, const Any& value)
877 : throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException );
878 : };
879 :
880 2753 : ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
881 : const Any& obj,
882 : rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ )
883 2753 : : mpAccess( pAccess_), mrInspectedObject( obj ), mpStaticImpl( pStaticImpl_ )
884 : {
885 : // Objekt als Interfaceholen
886 2753 : TypeClass eType = mrInspectedObject.getValueType().getTypeClass();
887 2753 : if( eType == TypeClass_INTERFACE )
888 : {
889 2438 : mxIface = *( Reference< XInterface >*)mrInspectedObject.getValue();
890 :
891 2438 : mxObjElementAccess = Reference<XElementAccess>::query( mxIface );
892 2438 : mxObjNameAccess = Reference<XNameAccess>::query( mxIface );
893 2438 : mxObjNameContainer = Reference<XNameContainer>::query( mxIface );
894 2438 : mxObjIndexAccess = Reference<XIndexAccess>::query( mxIface );
895 2438 : mxObjIndexContainer = Reference<XIndexContainer>::query( mxIface );
896 2438 : mxObjEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface );
897 2438 : mxObjIdlArray = Reference<XIdlArray>::query( mxIface );
898 : }
899 2753 : }
900 :
901 : // Methoden von XInterface
902 10708 : Any SAL_CALL ImplIntrospectionAdapter::queryInterface( const Type& rType )
903 : throw( RuntimeException )
904 : {
905 : Any aRet( ::cppu::queryInterface(
906 : rType,
907 : static_cast< XPropertySet * >( this ),
908 : static_cast< XFastPropertySet * >( this ),
909 10708 : static_cast< XPropertySetInfo * >( this ) ) );
910 10708 : if( !aRet.hasValue() )
911 6299 : aRet = OWeakObject::queryInterface( rType );
912 :
913 10708 : if( !aRet.hasValue() )
914 : {
915 : // Wrapper fuer die Objekt-Interfaces
916 3499 : if( ( mxObjElementAccess.is() && (aRet = ::cppu::queryInterface
917 320 : ( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() )
918 1832 : || ( mxObjNameAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() )
919 1808 : || ( mxObjNameContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() )
920 1786 : || ( mxObjIndexAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() )
921 1784 : || ( mxObjIndexContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() )
922 1784 : || ( mxObjEnumerationAccess .is() && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() )
923 3640 : || ( mxObjIdlArray.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() )
924 : )
925 : {
926 : }
927 : }
928 10708 : return aRet;
929 : }
930 :
931 :
932 : //***************************************************
933 : //*** Implementation von ImplIntrospectionAdapter ***
934 : //***************************************************
935 :
936 : // Methoden von XPropertySet
937 4 : Reference<XPropertySetInfo> ImplIntrospectionAdapter::getPropertySetInfo(void)
938 : throw( RuntimeException )
939 : {
940 4 : return (XPropertySetInfo *)this;
941 : }
942 :
943 558 : void ImplIntrospectionAdapter::setPropertyValue(const OUString& aPropertyName, const Any& aValue)
944 : throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
945 : {
946 558 : mpStaticImpl->setPropertyValue( mrInspectedObject, aPropertyName, aValue );
947 558 : }
948 :
949 1505 : Any ImplIntrospectionAdapter::getPropertyValue(const OUString& aPropertyName)
950 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
951 : {
952 1505 : return mpStaticImpl->getPropertyValue( mrInspectedObject, aPropertyName );
953 : }
954 :
955 0 : void ImplIntrospectionAdapter::addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
956 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
957 : {
958 0 : if( mxIface.is() )
959 : {
960 : Reference<XPropertySet> xPropSet =
961 0 : Reference<XPropertySet>::query( mxIface );
962 : //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
963 0 : if( xPropSet.is() )
964 0 : xPropSet->addPropertyChangeListener(aPropertyName, aListener);
965 : }
966 0 : }
967 :
968 0 : void ImplIntrospectionAdapter::removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
969 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
970 : {
971 0 : if( mxIface.is() )
972 : {
973 : Reference<XPropertySet> xPropSet =
974 0 : Reference<XPropertySet>::query( mxIface );
975 : //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
976 0 : if( xPropSet.is() )
977 0 : xPropSet->removePropertyChangeListener(aPropertyName, aListener);
978 : }
979 0 : }
980 :
981 0 : void ImplIntrospectionAdapter::addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
982 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
983 : {
984 0 : if( mxIface.is() )
985 : {
986 : Reference<XPropertySet> xPropSet =
987 0 : Reference<XPropertySet>::query( mxIface );
988 : //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
989 0 : if( xPropSet.is() )
990 0 : xPropSet->addVetoableChangeListener(aPropertyName, aListener);
991 : }
992 0 : }
993 :
994 0 : void ImplIntrospectionAdapter::removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
995 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
996 : {
997 0 : if( mxIface.is() )
998 : {
999 : Reference<XPropertySet> xPropSet =
1000 0 : Reference<XPropertySet>::query( mxIface );
1001 0 : if( xPropSet.is() )
1002 0 : xPropSet->removeVetoableChangeListener(aPropertyName, aListener);
1003 : }
1004 0 : }
1005 :
1006 :
1007 : // Methoden von XFastPropertySet
1008 0 : void ImplIntrospectionAdapter::setFastPropertyValue(sal_Int32, const Any&)
1009 : throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
1010 : {
1011 0 : }
1012 :
1013 0 : Any ImplIntrospectionAdapter::getFastPropertyValue(sal_Int32)
1014 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
1015 : {
1016 0 : return Any();
1017 : }
1018 :
1019 : // Methoden von XPropertySetInfo
1020 4 : Sequence< Property > ImplIntrospectionAdapter::getProperties(void) throw( RuntimeException )
1021 : {
1022 4 : return mpStaticImpl->getProperties();
1023 : }
1024 :
1025 0 : Property ImplIntrospectionAdapter::getPropertyByName(const OUString& Name)
1026 : throw( RuntimeException )
1027 : {
1028 0 : return mpAccess->getProperty( Name, PropertyConcept::ALL );
1029 : }
1030 :
1031 0 : sal_Bool ImplIntrospectionAdapter::hasPropertyByName(const OUString& Name)
1032 : throw( RuntimeException )
1033 : {
1034 0 : return mpAccess->hasProperty( Name, PropertyConcept::ALL );
1035 : }
1036 :
1037 : // Methoden von XElementAccess
1038 0 : Type ImplIntrospectionAdapter::getElementType(void) throw( RuntimeException )
1039 : {
1040 0 : return mxObjElementAccess->getElementType();
1041 : }
1042 :
1043 0 : sal_Bool ImplIntrospectionAdapter::hasElements(void) throw( RuntimeException )
1044 : {
1045 0 : return mxObjElementAccess->hasElements();
1046 : }
1047 :
1048 : // Methoden von XNameAccess
1049 0 : Any ImplIntrospectionAdapter::getByName(const OUString& Name)
1050 : throw( NoSuchElementException, WrappedTargetException, RuntimeException )
1051 : {
1052 0 : return mxObjNameAccess->getByName( Name );
1053 : }
1054 :
1055 0 : Sequence< OUString > ImplIntrospectionAdapter::getElementNames(void)
1056 : throw( RuntimeException )
1057 : {
1058 0 : return mxObjNameAccess->getElementNames();
1059 : }
1060 :
1061 0 : sal_Bool ImplIntrospectionAdapter::hasByName(const OUString& Name)
1062 : throw( RuntimeException )
1063 : {
1064 0 : return mxObjNameAccess->hasByName( Name );
1065 : }
1066 :
1067 : // Methoden von XNameContainer
1068 0 : void ImplIntrospectionAdapter::insertByName(const OUString& Name, const Any& Element)
1069 : throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
1070 : {
1071 0 : mxObjNameContainer->insertByName( Name, Element );
1072 0 : }
1073 :
1074 0 : void ImplIntrospectionAdapter::replaceByName(const OUString& Name, const Any& Element)
1075 : throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
1076 : {
1077 0 : mxObjNameContainer->replaceByName( Name, Element );
1078 0 : }
1079 :
1080 0 : void ImplIntrospectionAdapter::removeByName(const OUString& Name)
1081 : throw( NoSuchElementException, WrappedTargetException, RuntimeException )
1082 : {
1083 0 : mxObjNameContainer->removeByName( Name );
1084 0 : }
1085 :
1086 : // Methoden von XIndexAccess
1087 : // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const
1088 0 : sal_Int32 ImplIntrospectionAdapter::getCount(void) throw( RuntimeException )
1089 : {
1090 0 : return mxObjIndexAccess->getCount();
1091 : }
1092 :
1093 0 : Any ImplIntrospectionAdapter::getByIndex(sal_Int32 Index)
1094 : throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1095 : {
1096 0 : return mxObjIndexAccess->getByIndex( Index );
1097 : }
1098 :
1099 : // Methoden von XIndexContainer
1100 0 : void ImplIntrospectionAdapter::insertByIndex(sal_Int32 Index, const Any& Element)
1101 : throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1102 : {
1103 0 : mxObjIndexContainer->insertByIndex( Index, Element );
1104 0 : }
1105 :
1106 0 : void ImplIntrospectionAdapter::replaceByIndex(sal_Int32 Index, const Any& Element)
1107 : throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1108 : {
1109 0 : mxObjIndexContainer->replaceByIndex( Index, Element );
1110 0 : }
1111 :
1112 0 : void ImplIntrospectionAdapter::removeByIndex(sal_Int32 Index)
1113 : throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1114 : {
1115 0 : mxObjIndexContainer->removeByIndex( Index );
1116 0 : }
1117 :
1118 : // Methoden von XEnumerationAccess
1119 : // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const;
1120 0 : Reference<XEnumeration> ImplIntrospectionAdapter::createEnumeration(void) throw( RuntimeException )
1121 : {
1122 0 : return mxObjEnumerationAccess->createEnumeration();
1123 : }
1124 :
1125 : // Methoden von XIdlArray
1126 0 : void ImplIntrospectionAdapter::realloc(Any& array, sal_Int32 length)
1127 : throw( IllegalArgumentException, RuntimeException )
1128 : {
1129 0 : mxObjIdlArray->realloc( array, length );
1130 0 : }
1131 :
1132 0 : sal_Int32 ImplIntrospectionAdapter::getLen(const Any& array)
1133 : throw( IllegalArgumentException, RuntimeException )
1134 : {
1135 0 : return mxObjIdlArray->getLen( array );
1136 : }
1137 :
1138 0 : Any ImplIntrospectionAdapter::get(const Any& array, sal_Int32 index)
1139 : throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException )
1140 : {
1141 0 : return mxObjIdlArray->get( array, index );
1142 : }
1143 :
1144 0 : void ImplIntrospectionAdapter::set(Any& array, sal_Int32 index, const Any& value)
1145 : throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException )
1146 : {
1147 0 : mxObjIdlArray->set( array, index, value );
1148 0 : }
1149 :
1150 :
1151 : //**************************************************
1152 : //*** Implementation von ImplIntrospectionAccess ***
1153 : //**************************************************
1154 :
1155 : // Methoden von XIntrospectionAccess
1156 0 : sal_Int32 ImplIntrospectionAccess::getSuppliedMethodConcepts(void)
1157 : throw( RuntimeException )
1158 : {
1159 : return MethodConcept::DANGEROUS |
1160 : PROPERTY |
1161 : LISTENER |
1162 : ENUMERATION |
1163 : NAMECONTAINER |
1164 0 : INDEXCONTAINER;
1165 : }
1166 :
1167 0 : sal_Int32 ImplIntrospectionAccess::getSuppliedPropertyConcepts(void)
1168 : throw( RuntimeException )
1169 : {
1170 : return PropertyConcept::DANGEROUS |
1171 : PROPERTYSET |
1172 : ATTRIBUTES |
1173 0 : METHODS;
1174 : }
1175 :
1176 1279 : Property ImplIntrospectionAccess::getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
1177 : throw( NoSuchElementException, RuntimeException )
1178 : {
1179 1279 : Property aRet;
1180 1279 : sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
1181 1279 : sal_Bool bFound = sal_False;
1182 1279 : if( i != -1 )
1183 : {
1184 1279 : sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
1185 1279 : if( (PropertyConcepts & nConcept) != 0 )
1186 : {
1187 1279 : const Property* pProps = mpStaticImpl->getProperties().getConstArray();
1188 1279 : aRet = pProps[ i ];
1189 1279 : bFound = sal_True;
1190 : }
1191 : }
1192 1279 : if( !bFound )
1193 0 : throw NoSuchElementException() ;
1194 1279 : return aRet;
1195 : }
1196 :
1197 2471 : sal_Bool ImplIntrospectionAccess::hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
1198 : throw( RuntimeException )
1199 : {
1200 2471 : sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
1201 2471 : sal_Bool bRet = sal_False;
1202 2471 : if( i != -1 )
1203 : {
1204 1291 : sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
1205 1291 : if( (PropertyConcepts & nConcept) != 0 )
1206 1291 : bRet = sal_True;
1207 : }
1208 2471 : return bRet;
1209 : }
1210 :
1211 0 : Sequence< Property > ImplIntrospectionAccess::getProperties(sal_Int32 PropertyConcepts)
1212 : throw( RuntimeException )
1213 : {
1214 : // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
1215 : sal_Int32 nAllSupportedMask = PROPERTYSET |
1216 : ATTRIBUTES |
1217 0 : METHODS;
1218 0 : if( ( PropertyConcepts & nAllSupportedMask ) == nAllSupportedMask )
1219 : {
1220 0 : return mpStaticImpl->getProperties();
1221 : }
1222 :
1223 : // Gleiche Sequence wie beim vorigen mal?
1224 0 : if( mnLastPropertyConcept == PropertyConcepts )
1225 : {
1226 0 : return maLastPropertySeq;
1227 : }
1228 :
1229 : // Anzahl der zu liefernden Properties
1230 0 : sal_Int32 nCount = 0;
1231 :
1232 : // Es gibt zur Zeit keine DANGEROUS-Properties
1233 : // if( PropertyConcepts & DANGEROUS )
1234 : // nCount += mpStaticImpl->mnDangerousPropCount;
1235 0 : if( PropertyConcepts & PROPERTYSET )
1236 0 : nCount += mpStaticImpl->mnPropertySetPropCount;
1237 0 : if( PropertyConcepts & ATTRIBUTES )
1238 0 : nCount += mpStaticImpl->mnAttributePropCount;
1239 0 : if( PropertyConcepts & METHODS )
1240 0 : nCount += mpStaticImpl->mnMethodPropCount;
1241 :
1242 : // Sequence entsprechend der geforderten Anzahl reallocieren
1243 0 : ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen
1244 0 : pThis->maLastPropertySeq.realloc( nCount );
1245 0 : Property* pDestProps = pThis->maLastPropertySeq.getArray();
1246 :
1247 : // Alle Properties durchgehen und entsprechend der Concepte uebernehmen
1248 0 : Sequence<Property> aPropSeq = mpStaticImpl->getProperties();
1249 0 : const Property* pSourceProps = aPropSeq.getConstArray();
1250 0 : const sal_Int32* pConcepts = mpStaticImpl->getPropertyConcepts().getConstArray();
1251 0 : sal_Int32 nLen = aPropSeq.getLength();
1252 :
1253 0 : sal_Int32 iDest = 0;
1254 0 : for( sal_Int32 i = 0 ; i < nLen ; i++ )
1255 : {
1256 0 : sal_Int32 nConcept = pConcepts[ i ];
1257 0 : if( nConcept & PropertyConcepts )
1258 0 : pDestProps[ iDest++ ] = pSourceProps[ i ];
1259 : }
1260 :
1261 : // PropertyConcept merken, dies entspricht maLastPropertySeq
1262 0 : pThis->mnLastPropertyConcept = PropertyConcepts;
1263 :
1264 : // Zusammengebastelte Sequence liefern
1265 0 : return maLastPropertySeq;
1266 : }
1267 :
1268 1171 : Reference<XIdlMethod> ImplIntrospectionAccess::getMethod(const OUString& Name, sal_Int32 MethodConcepts)
1269 : throw( NoSuchMethodException, RuntimeException )
1270 : {
1271 1171 : Reference<XIdlMethod> xRet;
1272 1171 : sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
1273 1171 : if( i != -1 )
1274 : {
1275 :
1276 1171 : sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
1277 1171 : if( (MethodConcepts & nConcept) != 0 )
1278 : {
1279 1171 : const Reference<XIdlMethod>* pMethods = mpStaticImpl->getMethods().getConstArray();
1280 1171 : xRet = pMethods[i];
1281 : }
1282 : }
1283 1171 : if( !xRet.is() )
1284 0 : throw NoSuchMethodException();
1285 1171 : return xRet;
1286 : }
1287 :
1288 1338 : sal_Bool ImplIntrospectionAccess::hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
1289 : throw( RuntimeException )
1290 : {
1291 1338 : sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
1292 1338 : sal_Bool bRet = sal_False;
1293 1338 : if( i != -1 )
1294 : {
1295 1171 : sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
1296 1171 : if( (MethodConcepts & nConcept) != 0 )
1297 1171 : bRet = sal_True;
1298 : }
1299 1338 : return bRet;
1300 : }
1301 :
1302 234 : Sequence< Reference<XIdlMethod> > ImplIntrospectionAccess::getMethods(sal_Int32 MethodConcepts)
1303 : throw( RuntimeException )
1304 : {
1305 234 : ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen
1306 :
1307 : // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
1308 : sal_Int32 nAllSupportedMask = MethodConcept::DANGEROUS |
1309 : PROPERTY |
1310 : LISTENER |
1311 : ENUMERATION |
1312 : NAMECONTAINER |
1313 : INDEXCONTAINER |
1314 234 : MethodConcept_NORMAL_IMPL;
1315 234 : if( ( MethodConcepts & nAllSupportedMask ) == nAllSupportedMask )
1316 : {
1317 22 : return mpStaticImpl->getMethods();
1318 : }
1319 :
1320 : // Gleiche Sequence wie beim vorigen mal?
1321 212 : if( mnLastMethodConcept == MethodConcepts )
1322 : {
1323 20 : return maLastMethodSeq;
1324 : }
1325 :
1326 : // Methoden-Sequences besorgen
1327 192 : Sequence< Reference<XIdlMethod> > aMethodSeq = mpStaticImpl->getMethods();
1328 192 : const Reference<XIdlMethod>* pSourceMethods = aMethodSeq.getConstArray();
1329 192 : const sal_Int32* pConcepts = mpStaticImpl->getMethodConcepts().getConstArray();
1330 192 : sal_Int32 nLen = aMethodSeq.getLength();
1331 :
1332 : // Sequence entsprechend der geforderten Anzahl reallocieren
1333 : // Anders als bei den Properties kann die Anzahl nicht durch
1334 : // Zaehler in inspect() vorher ermittelt werden, da Methoden
1335 : // mehreren Konzepten angehoeren koennen
1336 192 : pThis->maLastMethodSeq.realloc( nLen );
1337 192 : Reference<XIdlMethod>* pDestMethods = pThis->maLastMethodSeq.getArray();
1338 :
1339 : // Alle Methods durchgehen und entsprechend der Concepte uebernehmen
1340 192 : sal_Int32 iDest = 0;
1341 15026 : for( sal_Int32 i = 0 ; i < nLen ; i++ )
1342 : {
1343 14834 : sal_Int32 nConcept = pConcepts[ i ];
1344 14834 : if( nConcept & MethodConcepts )
1345 3532 : pDestMethods[ iDest++ ] = pSourceMethods[ i ];
1346 :
1347 : #if OSL_DEBUG_LEVEL > 0
1348 : static bool debug = false;
1349 : if ( debug )
1350 : {
1351 : // Methode mit Concepts ausgeben
1352 : const Reference< XIdlMethod >& rxMethod = pSourceMethods[ i ];
1353 : OString aNameStr = OUStringToOString( rxMethod->getName(), osl_getThreadTextEncoding() );
1354 : OString ConceptStr;
1355 : if( nConcept & MethodConcept::DANGEROUS )
1356 : ConceptStr += "DANGEROUS |";
1357 : if( nConcept & MethodConcept::PROPERTY )
1358 : ConceptStr += "PROPERTY |";
1359 : if( nConcept & MethodConcept::LISTENER )
1360 : ConceptStr += "LISTENER |";
1361 : if( nConcept & MethodConcept::ENUMERATION )
1362 : ConceptStr += "ENUMERATION |";
1363 : if( nConcept & MethodConcept::NAMECONTAINER )
1364 : ConceptStr += "NAMECONTAINER |";
1365 : if( nConcept & MethodConcept::INDEXCONTAINER )
1366 : ConceptStr += "INDEXCONTAINER |";
1367 : OSL_TRACE( "Method %ld: %s, Concepts = %s", i, aNameStr.getStr(), ConceptStr.getStr() );
1368 : }
1369 : #endif
1370 : }
1371 :
1372 : // Auf die richtige Laenge bringen
1373 192 : pThis->maLastMethodSeq.realloc( iDest );
1374 :
1375 : // MethodConcept merken, dies entspricht maLastMethodSeq
1376 192 : pThis->mnLastMethodConcept = MethodConcepts;
1377 :
1378 : // Zusammengebastelte Sequence liefern
1379 192 : return maLastMethodSeq;
1380 : }
1381 :
1382 9 : Sequence< Type > ImplIntrospectionAccess::getSupportedListeners(void)
1383 : throw( RuntimeException )
1384 : {
1385 9 : return mpStaticImpl->getSupportedListeners();
1386 : }
1387 :
1388 2975 : Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type& rType )
1389 : throw( IllegalTypeException, RuntimeException )
1390 : {
1391 : // Gibt es schon einen Adapter?
1392 2975 : Reference< XInterface > xAdapter( maAdapter );
1393 2975 : if( !xAdapter.is() )
1394 : {
1395 2753 : xAdapter = *( new ImplIntrospectionAdapter( this, maInspectedObject, mpStaticImpl ) );
1396 2753 : maAdapter = xAdapter;
1397 : }
1398 :
1399 2975 : Reference<XInterface> xRet;
1400 2975 : xAdapter->queryInterface( rType ) >>= xRet;
1401 2975 : return xRet;
1402 : }
1403 :
1404 : // Methoden von XMaterialHolder
1405 12288 : Any ImplIntrospectionAccess::getMaterial(void) throw(RuntimeException)
1406 : {
1407 12288 : return maInspectedObject;
1408 : }
1409 :
1410 : // Hilfs-Funktion zur LowerCase-Wandlung eines OUString
1411 45558 : OUString toLower( OUString aUStr )
1412 : {
1413 : // Tabelle fuer XExactName pflegen
1414 45558 : OUString aOWStr( aUStr.getStr() );
1415 91116 : OUString aOWLowerStr = aOWStr.toAsciiLowerCase();
1416 45558 : OUString aLowerUStr( aOWLowerStr.getStr() );
1417 91116 : return aLowerUStr;
1418 : }
1419 :
1420 : // Methoden von XExactName
1421 2379 : OUString ImplIntrospectionAccess::getExactName( const OUString& rApproximateName ) throw( RuntimeException )
1422 : {
1423 2379 : OUString aRetStr;
1424 : LowerToExactNameMap::iterator aIt =
1425 2379 : mpStaticImpl->maLowerToExactNameMap.find( toLower( rApproximateName ) );
1426 2379 : if( !( aIt == mpStaticImpl->maLowerToExactNameMap.end() ) )
1427 2218 : aRetStr = (*aIt).second;
1428 2379 : return aRetStr;
1429 : }
1430 :
1431 :
1432 : //-----------------------------------------------------------------------------
1433 :
1434 339 : struct hashIntrospectionKey_Impl
1435 : {
1436 : Sequence< Reference<XIdlClass> > aIdlClasses;
1437 : Reference<XPropertySetInfo> xPropInfo;
1438 : Reference<XIdlClass> xImplClass;
1439 : sal_Int32 nHitCount;
1440 :
1441 228 : void IncHitCount() const { ((hashIntrospectionKey_Impl*)this)->nHitCount++; }
1442 : hashIntrospectionKey_Impl() : nHitCount( 0 ) {}
1443 : hashIntrospectionKey_Impl( const Sequence< Reference<XIdlClass> > & rIdlClasses,
1444 : const Reference<XPropertySetInfo> & rxPropInfo,
1445 : const Reference<XIdlClass> & rxImplClass );
1446 : };
1447 :
1448 251 : hashIntrospectionKey_Impl::hashIntrospectionKey_Impl
1449 : (
1450 : const Sequence< Reference<XIdlClass> > & rIdlClasses,
1451 : const Reference<XPropertySetInfo> & rxPropInfo,
1452 : const Reference<XIdlClass> & rxImplClass
1453 : )
1454 : : aIdlClasses( rIdlClasses )
1455 : , xPropInfo( rxPropInfo )
1456 : , xImplClass( rxImplClass )
1457 251 : , nHitCount( 0 )
1458 251 : {}
1459 :
1460 :
1461 : struct hashIntrospectionAccessCache_Impl
1462 : {
1463 274 : size_t operator()(const hashIntrospectionKey_Impl & rObj ) const
1464 : {
1465 274 : return (size_t)rObj.xImplClass.get() ^ (size_t)rObj.xPropInfo.get();
1466 : }
1467 :
1468 228 : bool operator()( const hashIntrospectionKey_Impl & rObj1,
1469 : const hashIntrospectionKey_Impl & rObj2 ) const
1470 : {
1471 456 : if( rObj1.xPropInfo != rObj2.xPropInfo
1472 228 : || rObj1.xImplClass != rObj2.xImplClass )
1473 0 : return sal_False;
1474 :
1475 228 : sal_Int32 nCount1 = rObj1.aIdlClasses.getLength();
1476 228 : sal_Int32 nCount2 = rObj2.aIdlClasses.getLength();
1477 228 : if( nCount1 != nCount2 )
1478 0 : return sal_False;
1479 :
1480 228 : const Reference<XIdlClass>* pRefs1 = rObj1.aIdlClasses.getConstArray();
1481 228 : const Reference<XIdlClass>* pRefs2 = rObj2.aIdlClasses.getConstArray();
1482 228 : return memcmp( pRefs1, pRefs2, nCount1 * sizeof( Reference<XIdlClass> ) ) == 0;
1483 : }
1484 :
1485 : };
1486 :
1487 : typedef boost::unordered_map
1488 : <
1489 : hashIntrospectionKey_Impl,
1490 : rtl::Reference< IntrospectionAccessStatic_Impl >,
1491 : hashIntrospectionAccessCache_Impl,
1492 : hashIntrospectionAccessCache_Impl
1493 : >
1494 : IntrospectionAccessCacheMap;
1495 :
1496 : // For XTypeProvider
1497 4860 : struct hashTypeProviderKey_Impl
1498 : {
1499 : Reference<XPropertySetInfo> xPropInfo;
1500 : Sequence< sal_Int8 > maImpIdSeq;
1501 : sal_Int32 nHitCount;
1502 :
1503 3204 : void IncHitCount() const { ((hashTypeProviderKey_Impl*)this)->nHitCount++; }
1504 : hashTypeProviderKey_Impl() : nHitCount( 0 ) {}
1505 : hashTypeProviderKey_Impl( const Reference<XPropertySetInfo> & rxPropInfo, const Sequence< sal_Int8 > & aImpIdSeq_ );
1506 : };
1507 :
1508 3541 : hashTypeProviderKey_Impl::hashTypeProviderKey_Impl
1509 : (
1510 : const Reference<XPropertySetInfo> & rxPropInfo,
1511 : const Sequence< sal_Int8 > & aImpIdSeq_
1512 : )
1513 : : xPropInfo( rxPropInfo )
1514 : , maImpIdSeq( aImpIdSeq_ )
1515 3541 : , nHitCount( 0 )
1516 3541 : {}
1517 :
1518 :
1519 : struct TypeProviderAccessCache_Impl
1520 : {
1521 : size_t operator()(const hashTypeProviderKey_Impl & rObj ) const;
1522 :
1523 4983 : bool operator()( const hashTypeProviderKey_Impl & rObj1,
1524 : const hashTypeProviderKey_Impl & rObj2 ) const
1525 : {
1526 4983 : if( rObj1.xPropInfo != rObj2.xPropInfo )
1527 1779 : return sal_False;
1528 :
1529 3204 : bool bEqual = false;
1530 3204 : sal_Int32 nLen1 = rObj1.maImpIdSeq.getLength();
1531 3204 : sal_Int32 nLen2 = rObj2.maImpIdSeq.getLength();
1532 3204 : if( nLen1 == nLen2 && nLen1 > 0 )
1533 : {
1534 3204 : const sal_Int8* pId1 = rObj1.maImpIdSeq.getConstArray();
1535 3204 : const sal_Int8* pId2 = rObj2.maImpIdSeq.getConstArray();
1536 3204 : bEqual = (memcmp( pId1, pId2, nLen1 * sizeof( sal_Int8 ) ) == 0 );
1537 : }
1538 3204 : return bEqual;
1539 : }
1540 : };
1541 :
1542 3878 : size_t TypeProviderAccessCache_Impl::operator()(const hashTypeProviderKey_Impl & rObj ) const
1543 : {
1544 3878 : const sal_Int32* pBytesAsInt32Array = (const sal_Int32*)rObj.maImpIdSeq.getConstArray();
1545 3878 : sal_Int32 nLen = rObj.maImpIdSeq.getLength();
1546 3878 : sal_Int32 nCount32 = nLen / 4;
1547 3878 : sal_Int32 nMod32 = nLen % 4;
1548 :
1549 : // XOR with full 32 bit values
1550 3878 : sal_Int32 nId32 = 0;
1551 : sal_Int32 i;
1552 19472 : for( i = 0 ; i < nCount32 ; i++ )
1553 15594 : nId32 ^= *(pBytesAsInt32Array++);
1554 :
1555 : // XOR with remaining byte values
1556 3878 : if( nMod32 )
1557 : {
1558 2 : const sal_Int8* pBytes = (const sal_Int8*)pBytesAsInt32Array;
1559 2 : sal_Int8* pInt8_Id32 = (sal_Int8*)&nId32;
1560 4 : for( i = 0 ; i < nMod32 ; i++ )
1561 2 : *(pInt8_Id32++) ^= *(pBytes++);
1562 : }
1563 :
1564 3878 : return (size_t)nId32;
1565 : }
1566 :
1567 :
1568 : typedef boost::unordered_map
1569 : <
1570 : hashTypeProviderKey_Impl,
1571 : rtl::Reference< IntrospectionAccessStatic_Impl >,
1572 : TypeProviderAccessCache_Impl,
1573 : TypeProviderAccessCache_Impl
1574 : >
1575 : TypeProviderAccessCacheMap;
1576 :
1577 : //*************************
1578 : //*** ImplIntrospection ***
1579 : //*************************
1580 :
1581 76 : struct OIntrospectionMutex
1582 : {
1583 : Mutex m_mutex;
1584 : };
1585 :
1586 20 : class ImplIntrospection : public XIntrospection
1587 : , public XServiceInfo
1588 : , public OIntrospectionMutex
1589 : , public OComponentHelper
1590 : {
1591 : // Implementation der Introspection.
1592 : rtl::Reference< IntrospectionAccessStatic_Impl > implInspect(const Any& aToInspectObj);
1593 :
1594 : // Save XMultiServiceFactory from createComponent
1595 : Reference<XMultiServiceFactory> m_xSMgr;
1596 :
1597 : // CoreReflection halten
1598 : Reference< XIdlReflection > mxCoreReflection;
1599 :
1600 : // Klassen, deren Methoden eine spezielle Rolle spielen
1601 : Reference<XIdlClass> mxElementAccessClass;
1602 : Reference<XIdlClass> mxNameContainerClass;
1603 : Reference<XIdlClass> mxNameAccessClass;
1604 : Reference<XIdlClass> mxIndexContainerClass;
1605 : Reference<XIdlClass> mxIndexAccessClass;
1606 : Reference<XIdlClass> mxEnumerationAccessClass;
1607 : Reference<XIdlClass> mxInterfaceClass;
1608 : Reference<XIdlClass> mxAggregationClass;
1609 : sal_Bool mbDisposed;
1610 :
1611 : sal_uInt16 mnCacheEntryCount;
1612 : sal_uInt16 mnTPCacheEntryCount;
1613 : IntrospectionAccessCacheMap* mpCache;
1614 : TypeProviderAccessCacheMap* mpTypeProviderCache;
1615 :
1616 : public:
1617 : ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr );
1618 :
1619 : // Methoden von XInterface
1620 : virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
1621 4222 : virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); }
1622 4140 : virtual void SAL_CALL release() throw() { OComponentHelper::release(); }
1623 :
1624 : // XTypeProvider
1625 : Sequence< Type > SAL_CALL getTypes( ) throw( RuntimeException );
1626 : Sequence<sal_Int8> SAL_CALL getImplementationId( ) throw( RuntimeException );
1627 :
1628 : // XServiceInfo
1629 : OUString SAL_CALL getImplementationName() throw();
1630 : sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw();
1631 : Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw();
1632 : static OUString SAL_CALL getImplementationName_Static( );
1633 : static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(void) throw();
1634 :
1635 : // Methoden von XIntrospection
1636 : virtual Reference<XIntrospectionAccess> SAL_CALL inspect(const Any& aToInspectObj)
1637 : throw( RuntimeException );
1638 :
1639 : protected:
1640 : // some XComponent part from OComponentHelper
1641 : virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
1642 : };
1643 :
1644 : enum MethodType
1645 : {
1646 : STANDARD_METHOD, // normale Methode, kein Bezug zu Properties oder Listenern
1647 : GETSET_METHOD, // gehoert zu einer get/set-Property
1648 : ADD_LISTENER_METHOD, // add-Methode einer Listener-Schnittstelle
1649 : REMOVE_LISTENER_METHOD, // remove-Methode einer Listener-Schnittstelle
1650 : INVALID_METHOD // Methode, deren Klasse nicht beruecksichtigt wird, z.B. XPropertySet
1651 : };
1652 :
1653 : // Ctor
1654 66 : ImplIntrospection::ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr )
1655 : : OComponentHelper( m_mutex )
1656 66 : , m_xSMgr( rXSMgr )
1657 : {
1658 66 : mnCacheEntryCount = 0;
1659 66 : mnTPCacheEntryCount = 0;
1660 66 : mpCache = NULL;
1661 66 : mpTypeProviderCache = NULL;
1662 :
1663 : // Spezielle Klassen holen
1664 : // Reference< XInterface > xServiceIface = m_xSMgr->createInstance("com.sun.star.reflection.CoreReflection");
1665 : // if( xServiceIface.is() )
1666 : // mxCoreReflection = Reference< XIdlReflection >::query( xServiceIface );
1667 66 : Reference< XPropertySet > xProps( rXSMgr, UNO_QUERY );
1668 : OSL_ASSERT( xProps.is() );
1669 66 : if (xProps.is())
1670 : {
1671 66 : Reference< XComponentContext > xContext;
1672 66 : xProps->getPropertyValue(
1673 66 : OUString("DefaultContext") ) >>= xContext;
1674 : OSL_ASSERT( xContext.is() );
1675 66 : if (xContext.is())
1676 : {
1677 66 : xContext->getValueByName(
1678 132 : OUString("/singletons/com.sun.star.reflection.theCoreReflection") ) >>= mxCoreReflection;
1679 : OSL_ENSURE( mxCoreReflection.is(), "### CoreReflection singleton not accessible!?" );
1680 66 : }
1681 : }
1682 66 : if (! mxCoreReflection.is())
1683 : {
1684 : throw DeploymentException(
1685 : OUString("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessible"),
1686 0 : Reference< XInterface >() );
1687 : }
1688 :
1689 66 : mxElementAccessClass = mxCoreReflection->forName("com.sun.star.container.XElementAccess");
1690 66 : mxNameContainerClass = mxCoreReflection->forName("com.sun.star.container.XNameContainer");
1691 66 : mxNameAccessClass = mxCoreReflection->forName("com.sun.star.container.XNameAccess");
1692 66 : mxIndexContainerClass = mxCoreReflection->forName("com.sun.star.container.XIndexContainer");
1693 66 : mxIndexAccessClass = mxCoreReflection->forName("com.sun.star.container.XIndexAccess");
1694 66 : mxEnumerationAccessClass = mxCoreReflection->forName("com.sun.star.container.XEnumerationAccess");
1695 66 : mxInterfaceClass = mxCoreReflection->forName("com.sun.star.uno.XInterface");
1696 66 : mxAggregationClass = mxCoreReflection->forName("com.sun.star.uno.XAggregation");
1697 66 : mbDisposed = sal_False;
1698 66 : }
1699 :
1700 : // XComponent
1701 65 : void ImplIntrospection::dispose() throw(::com::sun::star::uno::RuntimeException)
1702 : {
1703 65 : OComponentHelper::dispose();
1704 :
1705 : // Cache loeschen
1706 65 : delete mpCache;
1707 65 : mpCache = NULL;
1708 65 : delete mpTypeProviderCache;
1709 65 : mpTypeProviderCache = NULL;
1710 :
1711 65 : mxElementAccessClass = NULL;
1712 65 : mxNameContainerClass = NULL;
1713 65 : mxNameAccessClass = NULL;
1714 65 : mxIndexContainerClass = NULL;
1715 65 : mxIndexAccessClass = NULL;
1716 65 : mxEnumerationAccessClass = NULL;
1717 65 : mxInterfaceClass = NULL;
1718 65 : mxAggregationClass = NULL;
1719 65 : mbDisposed = sal_True;
1720 65 : }
1721 :
1722 :
1723 : //-----------------------------------------------------------------------------
1724 :
1725 : // XInterface
1726 1647 : Any ImplIntrospection::queryInterface( const Type & rType )
1727 : throw(::com::sun::star::uno::RuntimeException)
1728 : {
1729 : Any aRet( ::cppu::queryInterface(
1730 : rType,
1731 : static_cast< XIntrospection * >( this ),
1732 1647 : static_cast< XServiceInfo * >( this ) ) );
1733 :
1734 1647 : return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType ));
1735 : }
1736 :
1737 : // XTypeProvider
1738 0 : Sequence< Type > ImplIntrospection::getTypes()
1739 : throw( RuntimeException )
1740 : {
1741 : static OTypeCollection * s_pTypes = 0;
1742 0 : if (! s_pTypes)
1743 : {
1744 0 : MutexGuard aGuard( Mutex::getGlobalMutex() );
1745 0 : if (! s_pTypes)
1746 : {
1747 : static OTypeCollection s_aTypes(
1748 0 : ::getCppuType( (const Reference< XIntrospection > *)0 ),
1749 0 : ::getCppuType( (const Reference< XServiceInfo > *)0 ),
1750 0 : OComponentHelper::getTypes() );
1751 0 : s_pTypes = &s_aTypes;
1752 0 : }
1753 : }
1754 0 : return s_pTypes->getTypes();
1755 : }
1756 :
1757 0 : Sequence< sal_Int8 > ImplIntrospection::getImplementationId()
1758 : throw( RuntimeException )
1759 : {
1760 : static OImplementationId * s_pId = 0;
1761 0 : if (! s_pId)
1762 : {
1763 0 : MutexGuard aGuard( Mutex::getGlobalMutex() );
1764 0 : if (! s_pId)
1765 : {
1766 0 : static OImplementationId s_aId;
1767 0 : s_pId = &s_aId;
1768 0 : }
1769 : }
1770 0 : return s_pId->getImplementationId();
1771 : }
1772 :
1773 :
1774 : // XServiceInfo
1775 0 : OUString ImplIntrospection::getImplementationName() throw()
1776 : {
1777 0 : return getImplementationName_Static();
1778 : }
1779 :
1780 : // XServiceInfo
1781 0 : sal_Bool ImplIntrospection::supportsService(const OUString& ServiceName) throw()
1782 : {
1783 0 : Sequence< OUString > aSNL = getSupportedServiceNames();
1784 0 : const OUString * pArray = aSNL.getConstArray();
1785 0 : for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1786 0 : if( pArray[i] == ServiceName )
1787 0 : return sal_True;
1788 0 : return sal_False;
1789 : }
1790 :
1791 : // XServiceInfo
1792 0 : Sequence< OUString > ImplIntrospection::getSupportedServiceNames(void) throw()
1793 : {
1794 0 : return getSupportedServiceNames_Static();
1795 : }
1796 :
1797 : //*************************************************************************
1798 : // Helper XServiceInfo
1799 0 : OUString ImplIntrospection::getImplementationName_Static( )
1800 : {
1801 0 : return OUString::createFromAscii( IMPLEMENTATION_NAME );
1802 : }
1803 :
1804 : // ORegistryServiceManager_Static
1805 66 : Sequence< OUString > ImplIntrospection::getSupportedServiceNames_Static(void) throw()
1806 : {
1807 66 : Sequence< OUString > aSNS( 1 );
1808 66 : aSNS.getArray()[0] = OUString::createFromAscii( SERVICE_NAME );
1809 66 : return aSNS;
1810 : }
1811 :
1812 : //*************************************************************************
1813 :
1814 : // Methoden von XIntrospection
1815 4881 : Reference<XIntrospectionAccess> ImplIntrospection::inspect(const Any& aToInspectObj)
1816 : throw( RuntimeException )
1817 : {
1818 4881 : Reference<XIntrospectionAccess> xAccess;
1819 :
1820 4881 : if ( aToInspectObj.getValueType().getTypeClass() == TypeClass_TYPE )
1821 : {
1822 0 : Type aType;
1823 0 : aToInspectObj >>= aType;
1824 :
1825 0 : Reference< XIdlClass > xIdlClass = mxCoreReflection->forName(((Type*)(aToInspectObj.getValue()))->getTypeName());
1826 :
1827 0 : if ( xIdlClass.is() )
1828 : {
1829 0 : Any aRealInspectObj;
1830 0 : aRealInspectObj <<= xIdlClass;
1831 :
1832 0 : rtl::Reference< IntrospectionAccessStatic_Impl > pStaticImpl( implInspect( aRealInspectObj ) );
1833 0 : if( pStaticImpl.is() )
1834 0 : xAccess = new ImplIntrospectionAccess( aRealInspectObj, pStaticImpl );
1835 0 : }
1836 : }
1837 : else
1838 : {
1839 4881 : rtl::Reference< IntrospectionAccessStatic_Impl > pStaticImpl( implInspect( aToInspectObj ) );
1840 4881 : if( pStaticImpl.is() )
1841 3792 : xAccess = new ImplIntrospectionAccess( aToInspectObj, pStaticImpl );
1842 : }
1843 :
1844 4881 : return xAccess;
1845 : }
1846 :
1847 : //-----------------------------------------------------------------------------
1848 :
1849 : // Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces
1850 : struct hashInterface_Impl
1851 : {
1852 30174 : size_t operator()(const void* p) const
1853 : {
1854 30174 : return (size_t)p;
1855 : }
1856 : };
1857 :
1858 : struct eqInterface_Impl
1859 : {
1860 10556 : bool operator()(const void* p1, const void* p2) const
1861 : {
1862 10556 : return ( p1 == p2 );
1863 : }
1864 : };
1865 :
1866 : typedef boost::unordered_map
1867 : <
1868 : void*,
1869 : void*,
1870 : hashInterface_Impl,
1871 : eqInterface_Impl
1872 : >
1873 : CheckedInterfacesMap;
1874 :
1875 :
1876 :
1877 : // TODO: Spaeter auslagern
1878 96693 : Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XMultiServiceFactory > & xMgr )
1879 : {
1880 96693 : static Reference< XIdlReflection > xRefl;
1881 :
1882 : // void als Default-Klasse eintragen
1883 96693 : Reference<XIdlClass> xRetClass;
1884 96693 : typelib_TypeDescription * pTD = 0;
1885 96693 : rType.getDescription( &pTD );
1886 96693 : if( pTD )
1887 : {
1888 96693 : OUString sOWName( pTD->pTypeName );
1889 96693 : if( !xRefl.is() )
1890 : {
1891 65 : xRefl = Reference< XIdlReflection >( xMgr->createInstance("com.sun.star.reflection.CoreReflection"), UNO_QUERY );
1892 : OSL_ENSURE( xRefl.is(), "### no corereflection!" );
1893 : }
1894 96693 : xRetClass = xRefl->forName( sOWName );
1895 : }
1896 96693 : return xRetClass;
1897 : }
1898 :
1899 : // Implementation der Introspection.
1900 4881 : rtl::Reference< IntrospectionAccessStatic_Impl > ImplIntrospection::implInspect(const Any& aToInspectObj)
1901 : {
1902 4881 : MutexGuard aGuard( m_mutex );
1903 :
1904 : // Wenn die Introspection schon disposed ist, wird nur ein leeres Ergebnis geliefert
1905 4881 : if( mbDisposed )
1906 0 : return NULL;
1907 :
1908 : // Objekt untersuchen
1909 4881 : TypeClass eType = aToInspectObj.getValueType().getTypeClass();
1910 4881 : if( eType != TypeClass_INTERFACE && eType != TypeClass_STRUCT && eType != TypeClass_EXCEPTION )
1911 1089 : return NULL;
1912 :
1913 7584 : Reference<XInterface> x;
1914 3792 : if( eType == TypeClass_INTERFACE )
1915 : {
1916 : // Interface aus dem Any besorgen
1917 3551 : x = *(Reference<XInterface>*)aToInspectObj.getValue();
1918 3551 : if( !x.is() )
1919 0 : return NULL;
1920 : }
1921 :
1922 : // Haben wir schon eine Cache-Instanz
1923 3792 : if( !mpCache )
1924 65 : mpCache = new IntrospectionAccessCacheMap;
1925 3792 : if( !mpTypeProviderCache )
1926 65 : mpTypeProviderCache = new TypeProviderAccessCacheMap;
1927 3792 : IntrospectionAccessCacheMap& aCache = *mpCache;
1928 3792 : TypeProviderAccessCacheMap& aTPCache = *mpTypeProviderCache;
1929 :
1930 : // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz
1931 7584 : rtl::Reference< IntrospectionAccessStatic_Impl > pAccess;
1932 :
1933 : // Pruefen: Ist schon ein passendes Access-Objekt gecached?
1934 7584 : Sequence< Reference<XIdlClass> > SupportedClassSeq;
1935 7584 : Sequence< Type > SupportedTypesSeq;
1936 7584 : Reference<XTypeProvider> xTypeProvider;
1937 7584 : Reference<XIdlClass> xImplClass;
1938 7584 : Reference<XPropertySetInfo> xPropSetInfo;
1939 7584 : Reference<XPropertySet> xPropSet;
1940 :
1941 : // Look for interfaces XTypeProvider and PropertySet
1942 3792 : if( eType == TypeClass_INTERFACE )
1943 : {
1944 3551 : xTypeProvider = Reference<XTypeProvider>::query( x );
1945 3551 : if( xTypeProvider.is() )
1946 : {
1947 3541 : SupportedTypesSeq = xTypeProvider->getTypes();
1948 3541 : sal_Int32 nTypeCount = SupportedTypesSeq.getLength();
1949 3541 : if( nTypeCount )
1950 : {
1951 3541 : SupportedClassSeq.realloc( nTypeCount );
1952 3541 : Reference<XIdlClass>* pClasses = SupportedClassSeq.getArray();
1953 :
1954 3541 : const Type* pTypes = SupportedTypesSeq.getConstArray();
1955 95760 : for( sal_Int32 i = 0 ; i < nTypeCount ; i++ )
1956 : {
1957 92219 : pClasses[ i ] = TypeToIdlClass( pTypes[ i ], m_xSMgr );
1958 : }
1959 : // TODO: Caching!
1960 : }
1961 : }
1962 : else
1963 : {
1964 10 : xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
1965 10 : SupportedClassSeq.realloc( 1 );
1966 10 : SupportedClassSeq.getArray()[ 0 ] = xImplClass;
1967 : }
1968 :
1969 3551 : xPropSet = Reference<XPropertySet>::query( x );
1970 : // Jetzt versuchen, das PropertySetInfo zu bekommen
1971 3551 : if( xPropSet.is() )
1972 1305 : xPropSetInfo = xPropSet->getPropertySetInfo();
1973 : }
1974 : else
1975 : {
1976 241 : xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
1977 : }
1978 :
1979 3792 : if( xTypeProvider.is() )
1980 : {
1981 3541 : Sequence< sal_Int8 > aImpIdSeq = xTypeProvider->getImplementationId();
1982 3541 : sal_Int32 nIdLen = aImpIdSeq.getLength();
1983 :
1984 3541 : if( nIdLen )
1985 : {
1986 : // cache only, if the descriptor class is set
1987 3541 : hashTypeProviderKey_Impl aKeySeq( xPropSetInfo, aImpIdSeq );
1988 :
1989 3541 : TypeProviderAccessCacheMap::iterator aIt = aTPCache.find( aKeySeq );
1990 3541 : if( aIt == aTPCache.end() )
1991 : {
1992 : // not found
1993 : // Neue Instanz anlegen und unter dem gegebenen Key einfuegen
1994 337 : pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
1995 :
1996 : // Groesse begrenzen, alten Eintrag wieder rausschmeissen
1997 337 : if( mnTPCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE )
1998 : {
1999 : // Access mit dem kleinsten HitCount suchen
2000 52 : TypeProviderAccessCacheMap::iterator iter = aTPCache.begin();
2001 52 : TypeProviderAccessCacheMap::iterator end = aTPCache.end();
2002 52 : TypeProviderAccessCacheMap::iterator toDelete = iter;
2003 5356 : while( iter != end )
2004 : {
2005 5252 : if( (*iter).first.nHitCount < (*toDelete).first.nHitCount )
2006 47 : toDelete = iter;
2007 5252 : ++iter;
2008 : }
2009 52 : aTPCache.erase( toDelete );
2010 : }
2011 : else
2012 285 : mnTPCacheEntryCount++;
2013 :
2014 : // Neuer Eintrage rein in die Table
2015 337 : aKeySeq.nHitCount = 1;
2016 337 : aTPCache[ aKeySeq ] = pAccess;
2017 :
2018 : }
2019 : else
2020 : {
2021 : // Hit-Count erhoehen
2022 3204 : (*aIt).first.IncHitCount();
2023 3204 : return (*aIt).second;
2024 337 : }
2025 337 : }
2026 : }
2027 251 : else if( xImplClass.is() )
2028 : {
2029 : // cache only, if the descriptor class is set
2030 251 : hashIntrospectionKey_Impl aKeySeq( SupportedClassSeq, xPropSetInfo, xImplClass );
2031 :
2032 251 : IntrospectionAccessCacheMap::iterator aIt = aCache.find( aKeySeq );
2033 251 : if( aIt == aCache.end() )
2034 : {
2035 : // not found
2036 : // Neue Instanz anlegen und unter dem gegebenen Key einfuegen
2037 23 : pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
2038 :
2039 : // Groesse begrenzen, alten Eintrag wieder rausschmeissen
2040 23 : if( mnCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE )
2041 : {
2042 : // Access mit dem kleinsten HitCount suchen
2043 0 : IntrospectionAccessCacheMap::iterator iter = aCache.begin();
2044 0 : IntrospectionAccessCacheMap::iterator end = aCache.end();
2045 0 : IntrospectionAccessCacheMap::iterator toDelete = iter;
2046 0 : while( iter != end )
2047 : {
2048 0 : if( (*iter).first.nHitCount < (*toDelete).first.nHitCount )
2049 0 : toDelete = iter;
2050 0 : ++iter;
2051 : }
2052 0 : aCache.erase( toDelete );
2053 : }
2054 : else
2055 23 : mnCacheEntryCount++;
2056 :
2057 : // Neuer Eintrage rein in die Table
2058 23 : aKeySeq.nHitCount = 1;
2059 23 : aCache[ aKeySeq ] = pAccess;
2060 :
2061 : }
2062 : else
2063 : {
2064 : // Hit-Count erhoehen
2065 228 : (*aIt).first.IncHitCount();
2066 228 : return (*aIt).second;
2067 23 : }
2068 : }
2069 :
2070 : // Kein Access gecached -> neu anlegen
2071 : Property* pAllPropArray;
2072 : Reference<XInterface>* pInterfaces1;
2073 : Reference<XInterface>* pInterfaces2;
2074 : sal_Int16* pMapTypeArray;
2075 : sal_Int32* pPropertyConceptArray;
2076 : sal_Int32 i;
2077 :
2078 360 : if( !pAccess.is() )
2079 0 : pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
2080 :
2081 : // Referenzen auf wichtige Daten von pAccess
2082 360 : sal_Int32& rPropCount = pAccess->mnPropCount;
2083 360 : IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap;
2084 360 : IntrospectionNameMap& rMethodNameMap = pAccess->maMethodNameMap;
2085 360 : LowerToExactNameMap& rLowerToExactNameMap = pAccess->maLowerToExactNameMap;
2086 :
2087 : // Schon mal Pointer auf das eigene Property-Feld holen
2088 360 : pAllPropArray = pAccess->maAllPropertySeq.getArray();
2089 360 : pInterfaces1 = pAccess->aInterfaceSeq1.getArray();
2090 360 : pInterfaces2 = pAccess->aInterfaceSeq2.getArray();
2091 360 : pMapTypeArray = pAccess->maMapTypeSeq.getArray();
2092 360 : pPropertyConceptArray = pAccess->maPropertyConceptSeq.getArray();
2093 :
2094 : //*************************
2095 : //*** Analyse vornehmen ***
2096 : //*************************
2097 360 : if( eType == TypeClass_INTERFACE )
2098 : {
2099 : // Zunaechst nach speziellen Interfaces suchen, die fuer
2100 : // die Introspection von besonderer Bedeutung sind.
2101 :
2102 : // XPropertySet vorhanden?
2103 339 : if( xPropSet.is() && xPropSetInfo.is() )
2104 : {
2105 : // Gibt es auch ein FastPropertySet?
2106 201 : Reference<XFastPropertySet> xDummy = Reference<XFastPropertySet>::query( x );
2107 201 : sal_Bool bFast = pAccess->mbFastPropSet = xDummy.is();
2108 :
2109 402 : Sequence<Property> aPropSeq = xPropSetInfo->getProperties();
2110 201 : const Property* pProps = aPropSeq.getConstArray();
2111 201 : sal_Int32 nLen = aPropSeq.getLength();
2112 :
2113 : // Bei FastPropertySet muessen wir uns die Original-Handles merken
2114 201 : if( bFast )
2115 90 : pAccess->mpOrgPropertyHandleArray = new sal_Int32[ nLen ];
2116 :
2117 9860 : for( i = 0 ; i < nLen ; i++ )
2118 : {
2119 : // Property in eigene Liste uebernehmen
2120 : pAccess->checkPropertyArraysSize
2121 9659 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2122 9659 : Property& rProp = pAllPropArray[ rPropCount ];
2123 9659 : rProp = pProps[ i ];
2124 :
2125 9659 : if( bFast )
2126 5208 : pAccess->mpOrgPropertyHandleArray[ i ] = rProp.Handle;
2127 :
2128 : // PropCount als Handle fuer das eigene FastPropertySet eintragen
2129 9659 : rProp.Handle = rPropCount;
2130 :
2131 : // Art der Property merken
2132 9659 : pMapTypeArray[ rPropCount ] = MAP_PROPERTY_SET;
2133 9659 : pPropertyConceptArray[ rPropCount ] = PROPERTYSET;
2134 9659 : pAccess->mnPropertySetPropCount++;
2135 :
2136 : // Namen in Hashtable eintragen, wenn nicht schon bekannt
2137 9659 : OUString aPropName = rProp.Name;
2138 :
2139 : // Haben wir den Namen schon?
2140 9659 : IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2141 9659 : if( aIt == rPropNameMap.end() )
2142 : {
2143 : // Neuer Eintrag in die Hashtable
2144 9659 : rPropNameMap[ aPropName ] = rPropCount;
2145 :
2146 : // Tabelle fuer XExactName pflegen
2147 9659 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2148 : }
2149 : else
2150 : {
2151 : SAL_WARN( "stoc", "Introspection: Property \"" <<
2152 : aPropName << "\" found more than once in PropertySet" );
2153 : }
2154 :
2155 : // Count pflegen
2156 9659 : rPropCount++;
2157 9860 : }
2158 : }
2159 :
2160 : // Indizes in die Export-Tabellen
2161 339 : sal_Int32 iAllExportedMethod = 0;
2162 339 : sal_Int32 iAllSupportedListener = 0;
2163 :
2164 : // Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces
2165 339 : CheckedInterfacesMap aCheckedInterfacesMap;
2166 :
2167 : // Flag, ob XInterface-Methoden erfasst werden sollen
2168 : // (das darf nur einmal erfolgen, initial zulassen)
2169 339 : sal_Bool bXInterfaceIsInvalid = sal_False;
2170 :
2171 : // Flag, ob die XInterface-Methoden schon erfasst wurden. Wenn sal_True,
2172 : // wird bXInterfaceIsInvalid am Ende der Iface-Schleife aktiviert und
2173 : // XInterface-Methoden werden danach abgeklemmt.
2174 339 : sal_Bool bFoundXInterface = sal_False;
2175 :
2176 339 : sal_Int32 nClassCount = SupportedClassSeq.getLength();
2177 9640 : for( sal_Int32 nIdx = 0 ; nIdx < nClassCount; nIdx++ )
2178 : {
2179 9301 : Reference<XIdlClass> xImplClass2 = SupportedClassSeq.getConstArray()[nIdx];
2180 38967 : while( xImplClass2.is() )
2181 : {
2182 : // Interfaces der Implementation holen
2183 20365 : Sequence< Reference<XIdlClass> > aClassSeq = xImplClass2->getInterfaces();
2184 20365 : sal_Int32 nIfaceCount = aClassSeq.getLength();
2185 :
2186 20365 : aClassSeq.realloc( nIfaceCount + 1 );
2187 20365 : aClassSeq.getArray()[ nIfaceCount ] = xImplClass2;
2188 20365 : nIfaceCount++;
2189 :
2190 20365 : const Reference<XIdlClass>* pParamArray = aClassSeq.getConstArray();
2191 :
2192 40730 : for( sal_Int32 j = 0 ; j < nIfaceCount ; j++ )
2193 : {
2194 20365 : const Reference<XIdlClass>& rxIfaceClass = pParamArray[j];
2195 :
2196 : // Pruefen, ob das Interface schon beruecksichtigt wurde.
2197 20365 : XInterface* pIface = ( static_cast< XInterface* >( rxIfaceClass.get() ) );
2198 20365 : if( aCheckedInterfacesMap.count( pIface ) > 0 )
2199 : {
2200 : // Kennen wir schon
2201 10556 : continue;
2202 : }
2203 : else
2204 : {
2205 : // Sonst eintragen
2206 9809 : aCheckedInterfacesMap[ pIface ] = pIface;
2207 : }
2208 :
2209 : //********************************************************************
2210 :
2211 : // 2. Fields als Properties registrieren
2212 :
2213 : // Felder holen
2214 9809 : Sequence< Reference<XIdlField> > fields = rxIfaceClass->getFields();
2215 9809 : const Reference<XIdlField>* pFields = fields.getConstArray();
2216 9809 : sal_Int32 nLen = fields.getLength();
2217 :
2218 11792 : for( i = 0 ; i < nLen ; i++ )
2219 : {
2220 1983 : Reference<XIdlField> xField = pFields[i];
2221 3275 : Reference<XIdlClass> xPropType = xField->getType();
2222 :
2223 : // Ist die PropertySequence gross genug?
2224 : pAccess->checkPropertyArraysSize
2225 1983 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2226 :
2227 : // In eigenes Property-Array eintragen
2228 1983 : Property& rProp = pAllPropArray[ rPropCount ];
2229 3275 : OUString aFieldName = xField->getName();
2230 1983 : rProp.Name = aFieldName;
2231 1983 : rProp.Handle = rPropCount;
2232 3275 : Type aFieldType( xPropType->getTypeClass(), xPropType->getName() );
2233 1983 : rProp.Type = aFieldType;
2234 1983 : FieldAccessMode eAccessMode = xField->getAccessMode();
2235 695 : rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
2236 : eAccessMode == FieldAccessMode_CONST)
2237 3271 : ? READONLY : 0;
2238 :
2239 : // Namen in Hashtable eintragen
2240 3275 : OUString aPropName = rProp.Name;
2241 :
2242 : // Haben wir den Namen schon?
2243 1983 : IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2244 1983 : if( !( aIt == rPropNameMap.end() ) )
2245 691 : continue;
2246 :
2247 : // Neuer Eintrag in die Hashtable
2248 1292 : rPropNameMap[ aPropName ] = rPropCount;
2249 :
2250 : // Tabelle fuer XExactName pflegen
2251 1292 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2252 :
2253 : // Field merken
2254 1292 : pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
2255 2584 : pInterfaces1, rPropCount );
2256 1292 : pInterfaces1[ rPropCount ] = xField;
2257 :
2258 : // Art der Property merken
2259 1292 : pMapTypeArray[ rPropCount ] = MAP_FIELD;
2260 1292 : pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
2261 1292 : pAccess->mnAttributePropCount++;
2262 :
2263 : // Count pflegen
2264 1292 : rPropCount++;
2265 1292 : }
2266 :
2267 : //********************************************************************
2268 :
2269 : // 3. Methoden
2270 :
2271 : // Zaehler fuer die gefundenen Listener
2272 9809 : sal_Int32 nListenerCount = 0;
2273 :
2274 : // Alle Methoden holen und merken
2275 19618 : Sequence< Reference<XIdlMethod> > methods = rxIfaceClass->getMethods();
2276 9809 : const Reference<XIdlMethod>* pSourceMethods = methods.getConstArray();
2277 9809 : sal_Int32 nSourceMethodCount = methods.getLength();
2278 :
2279 : // 3. a) get/set- und Listener-Methoden suchen
2280 :
2281 : // Feld fuer Infos ueber die Methoden anlegen, damit spaeter leicht die Methoden
2282 : // gefunden werden koennen, die nicht im Zusammenhang mit Properties oder Listenern
2283 : // stehen. NEU: auch MethodConceptArray initialisieren
2284 9809 : MethodType* pMethodTypes = new MethodType[ nSourceMethodCount ];
2285 9809 : sal_Int32* pLocalMethodConcepts = new sal_Int32[ nSourceMethodCount ];
2286 71519 : for( i = 0 ; i < nSourceMethodCount ; i++ )
2287 : {
2288 61710 : pMethodTypes[ i ] = STANDARD_METHOD;
2289 61710 : pLocalMethodConcepts[ i ] = 0;
2290 : }
2291 :
2292 19618 : OUString aMethName;
2293 19618 : OUString aPropName;
2294 19618 : OUString aStartStr;
2295 71519 : for( i = 0 ; i < nSourceMethodCount ; i++ )
2296 : {
2297 : // Methode ansprechen
2298 61710 : const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
2299 61710 : sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
2300 :
2301 : // Namen besorgen
2302 61710 : aMethName = rxMethod_i->getName();
2303 :
2304 : // Methoden katalogisieren
2305 : // Alle (?) Methoden von XInterface filtern, damit z.B. nicht
2306 : // vom Scripting aus acquire oder release gerufen werden kann
2307 61710 : if( rxMethod_i->getDeclaringClass()->equals( mxInterfaceClass ) )
2308 : {
2309 : // XInterface-Methoden sind hiermit einmal beruecksichtigt
2310 29427 : bFoundXInterface = sal_True;
2311 :
2312 29427 : if( bXInterfaceIsInvalid )
2313 : {
2314 28410 : pMethodTypes[ i ] = INVALID_METHOD;
2315 28410 : continue;
2316 : }
2317 : else
2318 : {
2319 1017 : if( aMethName != OUString("queryInterface") )
2320 : {
2321 678 : rMethodConcept_i |= MethodConcept::DANGEROUS;
2322 678 : continue;
2323 : }
2324 : }
2325 : }
2326 32283 : else if( rxMethod_i->getDeclaringClass()->equals( mxAggregationClass ) )
2327 : {
2328 334 : if( aMethName == "setDelegator" )
2329 : {
2330 167 : rMethodConcept_i |= MethodConcept::DANGEROUS;
2331 167 : continue;
2332 : }
2333 : }
2334 31949 : else if( rxMethod_i->getDeclaringClass()->equals( mxElementAccessClass ) )
2335 : {
2336 : rMethodConcept_i |= ( NAMECONTAINER |
2337 : INDEXCONTAINER |
2338 570 : ENUMERATION );
2339 : }
2340 125416 : else if( rxMethod_i->getDeclaringClass()->equals( mxNameContainerClass ) ||
2341 94037 : rxMethod_i->getDeclaringClass()->equals( mxNameAccessClass ) )
2342 : {
2343 605 : rMethodConcept_i |= NAMECONTAINER;
2344 : }
2345 123096 : else if( rxMethod_i->getDeclaringClass()->equals( mxIndexContainerClass ) ||
2346 92322 : rxMethod_i->getDeclaringClass()->equals( mxIndexAccessClass ) )
2347 : {
2348 12 : rMethodConcept_i |= INDEXCONTAINER;
2349 : }
2350 30762 : else if( rxMethod_i->getDeclaringClass()->equals( mxEnumerationAccessClass ) )
2351 : {
2352 40 : rMethodConcept_i |= ENUMERATION;
2353 : }
2354 :
2355 : // Wenn der Name zu kurz ist, wird's sowieso nichts
2356 32455 : if( aMethName.getLength() <= 3 )
2357 13 : continue;
2358 :
2359 : // Ist es eine get-Methode?
2360 32442 : aStartStr = aMethName.copy( 0, 3 );
2361 32442 : if( aStartStr == "get" )
2362 : {
2363 : // Namen der potentiellen Property
2364 11127 : aPropName = aMethName.copy( 3 );
2365 :
2366 : // get-Methode darf keinen Parameter haben
2367 11127 : Sequence< Reference<XIdlClass> > getParams = rxMethod_i->getParameterTypes();
2368 11127 : if( getParams.getLength() > 0 )
2369 : {
2370 3597 : continue;
2371 : }
2372 :
2373 : // Haben wir den Namen schon?
2374 7530 : IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2375 7530 : if( !( aIt == rPropNameMap.end() ) )
2376 : {
2377 : /* TODO
2378 : OSL_TRACE(
2379 : String( "Introspection: Property \"" ) +
2380 : OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2381 : String( "\" found more than once" ) );
2382 : */
2383 1666 : continue;
2384 : }
2385 :
2386 : // Eine readonly-Property ist es jetzt mindestens schon
2387 5864 : rMethodConcept_i |= PROPERTY;
2388 :
2389 5864 : pMethodTypes[i] = GETSET_METHOD;
2390 11728 : Reference<XIdlClass> xGetRetType = rxMethod_i->getReturnType();
2391 :
2392 : // Ist die PropertySequence gross genug?
2393 : pAccess->checkPropertyArraysSize
2394 5864 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2395 :
2396 : // In eigenes Property-Array eintragen
2397 5864 : Property& rProp = pAllPropArray[ rPropCount ];
2398 5864 : rProp.Name = aPropName;
2399 5864 : rProp.Handle = rPropCount;
2400 5864 : rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
2401 5864 : rProp.Attributes = READONLY;
2402 :
2403 : // Neuer Eintrag in die Hashtable
2404 5864 : rPropNameMap[ aPropName ] = rPropCount;
2405 :
2406 : // Tabelle fuer XExactName pflegen
2407 5864 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2408 :
2409 : // get-Methode merken
2410 5864 : pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
2411 11728 : pInterfaces1, rPropCount );
2412 5864 : pInterfaces1[ rPropCount ] = rxMethod_i;
2413 :
2414 : // Art der Property merken
2415 5864 : pMapTypeArray[ rPropCount ] = MAP_GETSET;
2416 5864 : pPropertyConceptArray[ rPropCount ] = METHODS;
2417 5864 : pAccess->mnMethodPropCount++;
2418 :
2419 : // Passende set-Methode suchen
2420 : sal_Int32 k;
2421 57655 : for( k = 0 ; k < nSourceMethodCount ; k++ )
2422 : {
2423 : // Methode ansprechen
2424 51791 : const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
2425 :
2426 : // Nur Methoden nehmen, die nicht schon zugeordnet sind
2427 51791 : if( k == i || pMethodTypes[k] != STANDARD_METHOD )
2428 79050 : continue;
2429 :
2430 : // Name holen und auswerten
2431 23587 : OUString aMethName2 = rxMethod_k->getName();
2432 24532 : OUString aStartStr2 = aMethName2.copy( 0, 3 );
2433 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2434 23587 : if( !( aStartStr2 == "set" ) )
2435 21032 : continue;
2436 :
2437 : // Ist es denn der gleiche Name?
2438 3500 : OUString aPropName2 = aMethName2.copy( 3 );
2439 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2440 2555 : if( !( aPropName == aPropName2 ) )
2441 1544 : continue;
2442 :
2443 : // set-Methode muss void returnen
2444 1956 : Reference<XIdlClass> xSetRetType = rxMethod_k->getReturnType();
2445 1011 : if( xSetRetType->getTypeClass() != TypeClass_VOID )
2446 : {
2447 44 : continue;
2448 : }
2449 :
2450 : // set-Methode darf nur einen Parameter haben
2451 1912 : Sequence< Reference<XIdlClass> > setParams = rxMethod_k->getParameterTypes();
2452 967 : sal_Int32 nParamCount = setParams.getLength();
2453 967 : if( nParamCount != 1 )
2454 : {
2455 22 : continue;
2456 : }
2457 :
2458 : // Jetzt muss nur noch der return-Typ dem Parameter-Typ entsprechen
2459 945 : const Reference<XIdlClass>* pParamArray2 = setParams.getConstArray();
2460 1890 : Reference<XIdlClass> xParamType = pParamArray2[ 0 ];
2461 945 : if( xParamType->equals( xGetRetType ) )
2462 : {
2463 945 : pLocalMethodConcepts[ k ] = PROPERTY;
2464 :
2465 945 : pMethodTypes[k] = GETSET_METHOD;
2466 :
2467 : // ReadOnly-Flag wieder loschen
2468 945 : rProp.Attributes &= ~READONLY;
2469 :
2470 : // set-Methode merken
2471 945 : pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
2472 1890 : pInterfaces2, rPropCount );
2473 945 : pInterfaces2[ rPropCount ] = rxMethod_k;
2474 : }
2475 945 : }
2476 :
2477 : // Count pflegen
2478 11728 : rPropCount++;
2479 : }
2480 :
2481 : // Ist es eine addListener-Methode?
2482 21315 : else if( aStartStr == "add" )
2483 : {
2484 3149 : OUString aListenerStr( "Listener" );
2485 :
2486 : // Namen der potentiellen Property
2487 3149 : sal_Int32 nStrLen = aMethName.getLength();
2488 3149 : sal_Int32 nCopyLen = nStrLen - aListenerStr.getLength();
2489 5857 : OUString aEndStr = aMethName.copy( nCopyLen > 0 ? nCopyLen : 0 );
2490 :
2491 : // Endet das Teil auf Listener?
2492 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2493 3149 : if( !( aEndStr == aListenerStr ) )
2494 441 : continue;
2495 :
2496 : // Welcher Listener?
2497 5416 : OUString aListenerName = aMethName.copy( 3, nStrLen - aListenerStr.getLength() - 3 );
2498 :
2499 : // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
2500 : // - Rueckgabe-Typ
2501 : // - Anzahl und Art der Parameter
2502 :
2503 :
2504 : // Passende remove-Methode suchen, sonst gilt's nicht
2505 : sal_Int32 k;
2506 32539 : for( k = 0 ; k < nSourceMethodCount ; k++ )
2507 : {
2508 : // Methode ansprechen
2509 29831 : const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
2510 :
2511 : // Nur Methoden nehmen, die nicht schon zugeordnet sind
2512 29831 : if( k == i || pMethodTypes[k] != STANDARD_METHOD )
2513 40549 : continue;
2514 :
2515 : // Name holen und auswerten
2516 16405 : OUString aMethName2 = rxMethod_k->getName();
2517 16405 : sal_Int32 nNameLen = aMethName2.getLength();
2518 16405 : sal_Int32 nCopyLen2 = (nNameLen < 6) ? nNameLen : 6;
2519 19113 : OUString aStartStr2 = aMethName2.copy( 0, nCopyLen2 );
2520 19113 : OUString aRemoveStr("remove" );
2521 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2522 16405 : if( !( aStartStr2 == aRemoveStr ) )
2523 12374 : continue;
2524 :
2525 : // Ist es denn der gleiche Listener?
2526 4031 : if( aMethName2.getLength() - aRemoveStr.getLength() <= aListenerStr.getLength() )
2527 116 : continue;
2528 : OUString aListenerName2 = aMethName2.copy
2529 6623 : ( 6, aMethName2.getLength() - aRemoveStr.getLength() - aListenerStr.getLength() );
2530 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2531 3915 : if( !( aListenerName == aListenerName2 ) )
2532 1207 : continue;
2533 :
2534 : // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
2535 : // - Rueckgabe-Typ
2536 : // - Anzahl und Art der Parameter
2537 :
2538 :
2539 : // Methoden sind als Listener-Schnittstelle erkannt
2540 2708 : rMethodConcept_i |= LISTENER;
2541 2708 : pLocalMethodConcepts[ k ] |= LISTENER;
2542 :
2543 2708 : pMethodTypes[i] = ADD_LISTENER_METHOD;
2544 2708 : pMethodTypes[k] = REMOVE_LISTENER_METHOD;
2545 2708 : nListenerCount++;
2546 5416 : }
2547 : }
2548 : }
2549 :
2550 :
2551 : // Jetzt koennen noch SET-Methoden ohne zugehoerige GET-Methode existieren,
2552 : // diese muessen zu Write-Only-Properties gemachte werden.
2553 71519 : for( i = 0 ; i < nSourceMethodCount ; i++ )
2554 : {
2555 : // Methode ansprechen
2556 61710 : const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
2557 :
2558 : // Nur Methoden nehmen, die nicht schon zugeordnet sind
2559 61710 : if( pMethodTypes[i] != STANDARD_METHOD )
2560 40635 : continue;
2561 :
2562 : // Namen besorgen
2563 21075 : aMethName = rxMethod_i->getName();
2564 :
2565 : // Wenn der Name zu kurz ist, wird's sowieso nichts
2566 21075 : if( aMethName.getLength() <= 3 )
2567 13 : continue;
2568 :
2569 : // Ist es eine set-Methode ohne zugehoerige get-Methode?
2570 21062 : aStartStr = aMethName.copy( 0, 3 );
2571 21062 : if( aStartStr == "set" )
2572 : {
2573 : // Namen der potentiellen Property
2574 1835 : aPropName = aMethName.copy( 3 );
2575 :
2576 : // set-Methode muss void returnen
2577 1835 : Reference<XIdlClass> xSetRetType = rxMethod_i->getReturnType();
2578 1835 : if( xSetRetType->getTypeClass() != TypeClass_VOID )
2579 : {
2580 54 : continue;
2581 : }
2582 :
2583 : // set-Methode darf nur einen Parameter haben
2584 2302 : Sequence< Reference<XIdlClass> > setParams = rxMethod_i->getParameterTypes();
2585 1781 : sal_Int32 nParamCount = setParams.getLength();
2586 1781 : if( nParamCount != 1 )
2587 : {
2588 810 : continue;
2589 : }
2590 :
2591 : // Haben wir den Namen schon?
2592 971 : IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2593 971 : if( !( aIt == rPropNameMap.end() ) )
2594 : {
2595 : /* TODO:
2596 : OSL_TRACE(
2597 : String( "Introspection: Property \"" ) +
2598 : OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2599 : String( "\" found more than once" ) );
2600 : */
2601 450 : continue;
2602 : }
2603 :
2604 : // Alles klar, es ist eine Write-Only-Property
2605 521 : pLocalMethodConcepts[ i ] = PROPERTY;
2606 :
2607 521 : pMethodTypes[i] = GETSET_METHOD;
2608 1042 : Reference<XIdlClass> xGetRetType = setParams.getConstArray()[0];
2609 :
2610 : // Ist die PropertySequence gross genug?
2611 : pAccess->checkPropertyArraysSize
2612 521 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2613 :
2614 : // In eigenes Property-Array eintragen
2615 521 : Property& rProp = pAllPropArray[ rPropCount ];
2616 521 : rProp.Name = aPropName;
2617 521 : rProp.Handle = rPropCount;
2618 521 : rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
2619 521 : rProp.Attributes = 0; // PROPERTY_WRITEONLY ???
2620 :
2621 : // Neuer Eintrag in die Hashtable
2622 521 : rPropNameMap[ aPropName ] = rPropCount;
2623 :
2624 : // Tabelle fuer XExactName pflegen
2625 521 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2626 :
2627 : // set-Methode merken
2628 521 : pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
2629 1042 : pInterfaces2, rPropCount );
2630 521 : pInterfaces2[ rPropCount ] = rxMethod_i;
2631 :
2632 : // Art der Property merken
2633 521 : pMapTypeArray[ rPropCount ] = MAP_SETONLY;
2634 521 : pPropertyConceptArray[ rPropCount ] = METHODS;
2635 521 : pAccess->mnMethodPropCount++;
2636 :
2637 : // Count pflegen
2638 1042 : rPropCount++;
2639 : }
2640 : }
2641 :
2642 :
2643 : //********************************************************************
2644 :
2645 : // 4. Methoden in die Gesamt-Sequence uebernehmen
2646 :
2647 : // Wieviele Methoden muessen in die Method-Sequence?
2648 9809 : sal_Int32 nExportedMethodCount = 0;
2649 9809 : sal_Int32 nSupportedListenerCount = 0;
2650 71519 : for( i = 0 ; i < nSourceMethodCount ; i++ )
2651 : {
2652 61710 : if( pMethodTypes[ i ] != INVALID_METHOD )
2653 : {
2654 33300 : nExportedMethodCount++;
2655 : }
2656 61710 : if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
2657 : {
2658 2708 : nSupportedListenerCount++;
2659 : }
2660 : }
2661 :
2662 : // Sequences im Access-Objekt entsprechend aufbohren
2663 9809 : pAccess->maAllMethodSeq.realloc( nExportedMethodCount + iAllExportedMethod );
2664 9809 : pAccess->maMethodConceptSeq.realloc( nExportedMethodCount + iAllExportedMethod );
2665 9809 : pAccess->maSupportedListenerSeq.realloc( nSupportedListenerCount + iAllSupportedListener );
2666 :
2667 : // Methoden reinschreiben
2668 9809 : Reference<XIdlMethod>* pDestMethods = pAccess->maAllMethodSeq.getArray();
2669 9809 : sal_Int32* pMethodConceptArray = pAccess->maMethodConceptSeq.getArray();
2670 9809 : Type* pListenerClassRefs = pAccess->maSupportedListenerSeq.getArray();
2671 71519 : for( i = 0 ; i < nSourceMethodCount ; i++ )
2672 : {
2673 61710 : if( pMethodTypes[ i ] != INVALID_METHOD )
2674 : {
2675 : // Methode ansprechen
2676 33300 : const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
2677 :
2678 : // Namen in Hashtable eintragen, wenn nicht schon bekannt
2679 33300 : OUString aMethName2 = rxMethod->getName();
2680 33300 : IntrospectionNameMap::iterator aIt = rMethodNameMap.find( aMethName2 );
2681 33300 : if( aIt == rMethodNameMap.end() )
2682 : {
2683 : // Eintragen
2684 25754 : rMethodNameMap[ aMethName2 ] = iAllExportedMethod;
2685 :
2686 : // Tabelle fuer XExactName pflegen
2687 25754 : rLowerToExactNameMap[ toLower( aMethName2 ) ] = aMethName2;
2688 : }
2689 : else
2690 : {
2691 7546 : sal_Int32 iHashResult = (*aIt).second;
2692 :
2693 7546 : Reference<XIdlMethod> xExistingMethod = pDestMethods[ iHashResult ];
2694 :
2695 : Reference< XIdlClass > xExistingMethClass =
2696 8310 : xExistingMethod->getDeclaringClass();
2697 8310 : Reference< XIdlClass > xNewMethClass = rxMethod->getDeclaringClass();
2698 7546 : if( xExistingMethClass->equals( xNewMethClass ) )
2699 7546 : continue;
2700 : }
2701 :
2702 26518 : pDestMethods[ iAllExportedMethod ] = rxMethod;
2703 :
2704 : // Wenn kein Concept gesetzt wurde, ist die Methode "normal"
2705 26518 : sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
2706 26518 : if( !rMethodConcept_i )
2707 14083 : rMethodConcept_i = MethodConcept_NORMAL_IMPL;
2708 26518 : pMethodConceptArray[ iAllExportedMethod ] = rMethodConcept_i;
2709 26518 : iAllExportedMethod++;
2710 : }
2711 54928 : if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
2712 : {
2713 : // Klasse des Listeners ermitteln
2714 2101 : const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
2715 :
2716 : // void als Default-Klasse eintragen
2717 2101 : Reference<XIdlClass> xListenerClass = TypeToIdlClass( getCppuVoidType(), m_xSMgr );
2718 : // ALT: Reference<XIdlClass> xListenerClass = Void_getReflection()->getIdlClass();
2719 :
2720 : // 1. Moeglichkeit: Parameter nach einer Listener-Klasse durchsuchen
2721 : // Nachteil: Superklassen muessen rekursiv durchsucht werden
2722 4202 : Sequence< Reference<XIdlClass> > aParams = rxMethod->getParameterTypes();
2723 2101 : const Reference<XIdlClass>* pParamArray2 = aParams.getConstArray();
2724 :
2725 4202 : Reference<XIdlClass> xEventListenerClass = TypeToIdlClass( getCppuType( (Reference<XEventListener>*) NULL ), m_xSMgr );
2726 : // ALT: Reference<XIdlClass> xEventListenerClass = XEventListener_getReflection()->getIdlClass();
2727 2101 : sal_Int32 nParamCount = aParams.getLength();
2728 : sal_Int32 k;
2729 2619 : for( k = 0 ; k < nParamCount ; k++ )
2730 : {
2731 2618 : const Reference<XIdlClass>& rxClass = pParamArray2[k];
2732 :
2733 : // Sind wir von einem Listener abgeleitet?
2734 12222 : if( rxClass->equals( xEventListenerClass ) ||
2735 11354 : isDerivedFrom( rxClass, xEventListenerClass ) )
2736 : {
2737 2100 : xListenerClass = rxClass;
2738 2100 : break;
2739 : }
2740 : }
2741 :
2742 : // 2. Moeglichkeit: Namen der Methode auswerden
2743 : // Nachteil: geht nicht bei Test-Listenern, die es nicht gibt
2744 : //aMethName = rxMethod->getName();
2745 : //aListenerName = aMethName.Copy( 3, aMethName.Len()-8-3 );
2746 : //Reference<XIdlClass> xListenerClass = reflection->forName( aListenerName );
2747 4202 : Type aListenerType( TypeClass_INTERFACE, xListenerClass->getName() );
2748 2101 : pListenerClassRefs[ iAllSupportedListener ] = aListenerType;
2749 4202 : iAllSupportedListener++;
2750 : }
2751 : }
2752 :
2753 : // Wenn in diesem Durchlauf XInterface-Methoden
2754 : // dabei waren, diese zukuenftig ignorieren
2755 9809 : if( bFoundXInterface )
2756 9809 : bXInterfaceIsInvalid = sal_True;
2757 :
2758 9809 : delete[] pMethodTypes;
2759 9809 : delete[] pLocalMethodConcepts;
2760 9809 : }
2761 :
2762 : // Super-Klasse(n) vorhanden? Dann dort fortsetzen
2763 40730 : Sequence< Reference<XIdlClass> > aSuperClassSeq = xImplClass2->getSuperclasses();
2764 :
2765 : // Zur Zeit wird nur von einer Superklasse ausgegangen
2766 20365 : if( aSuperClassSeq.getLength() >= 1 )
2767 : {
2768 11064 : xImplClass2 = aSuperClassSeq.getConstArray()[0];
2769 : OSL_ENSURE( xImplClass2.is(), "super class null" );
2770 : }
2771 : else
2772 : {
2773 9301 : xImplClass2 = NULL;
2774 : }
2775 20365 : }
2776 9301 : }
2777 :
2778 : // Anzahl der exportierten Methoden uebernehmen und Sequences anpassen
2779 : // (kann abweichen, weil doppelte Methoden erst nach der Ermittlung
2780 : // von nExportedMethodCount herausgeworfen werden)
2781 339 : sal_Int32& rMethCount = pAccess->mnMethCount;
2782 339 : rMethCount = iAllExportedMethod;
2783 339 : pAccess->maAllMethodSeq.realloc( rMethCount );
2784 339 : pAccess->maMethodConceptSeq.realloc( rMethCount );
2785 :
2786 : // Groesse der Property-Sequences anpassen
2787 339 : pAccess->maAllPropertySeq.realloc( rPropCount );
2788 339 : pAccess->maPropertyConceptSeq.realloc( rPropCount );
2789 339 : pAccess->maMapTypeSeq.realloc( rPropCount );
2790 : }
2791 : // Bei structs Fields als Properties registrieren
2792 : else //if( eType == TypeClass_STRUCT )
2793 : {
2794 : // Ist es ein Interface oder eine struct?
2795 : //Reference<XIdlClass> xClassRef = aToInspectObj.getReflection()->getIdlClass();
2796 21 : Reference<XIdlClass> xClassRef = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
2797 21 : if( !xClassRef.is() )
2798 : {
2799 : SAL_WARN( "stoc", "Can't get XIdlClass from Reflection" );
2800 0 : return pAccess;
2801 : }
2802 :
2803 : // Felder holen
2804 42 : Sequence< Reference<XIdlField> > fields = xClassRef->getFields();
2805 21 : const Reference<XIdlField>* pFields = fields.getConstArray();
2806 21 : sal_Int32 nLen = fields.getLength();
2807 :
2808 110 : for( i = 0 ; i < nLen ; i++ )
2809 : {
2810 89 : Reference<XIdlField> xField = pFields[i];
2811 178 : Reference<XIdlClass> xPropType = xField->getType();
2812 178 : OUString aPropName = xField->getName();
2813 :
2814 : // Ist die PropertySequence gross genug?
2815 : pAccess->checkPropertyArraysSize
2816 89 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2817 :
2818 : // In eigenes Property-Array eintragen
2819 89 : Property& rProp = pAllPropArray[ rPropCount ];
2820 89 : rProp.Name = aPropName;
2821 89 : rProp.Handle = rPropCount;
2822 89 : rProp.Type = Type( xPropType->getTypeClass(), xPropType->getName() );
2823 89 : FieldAccessMode eAccessMode = xField->getAccessMode();
2824 89 : rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
2825 : eAccessMode == FieldAccessMode_CONST)
2826 89 : ? READONLY : 0;
2827 :
2828 : //FieldAccessMode eAccessMode = xField->getAccessMode();
2829 : //rProp.Attributes = (eAccessMode == FieldAccessMode::READONLY || eAccessMode == CONST)
2830 : //? PropertyAttribute::READONLY : 0;
2831 :
2832 : // Namen in Hashtable eintragen
2833 89 : rPropNameMap[ aPropName ] = rPropCount;
2834 :
2835 : // Tabelle fuer XExactName pflegen
2836 89 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2837 :
2838 : // Field merken
2839 89 : pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
2840 178 : pInterfaces1, rPropCount );
2841 89 : pInterfaces1[ rPropCount ] = xField;
2842 :
2843 : // Art der Property merken
2844 89 : pMapTypeArray[ rPropCount ] = MAP_FIELD;
2845 89 : pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
2846 89 : pAccess->mnAttributePropCount++;
2847 :
2848 : // Count pflegen
2849 89 : rPropCount++;
2850 110 : }
2851 : }
2852 :
2853 : // Property-Sequence auf die richtige Laenge bringen
2854 360 : pAccess->maAllPropertySeq.realloc( pAccess->mnPropCount );
2855 :
2856 5241 : return pAccess;
2857 : }
2858 :
2859 : //*************************************************************************
2860 66 : Reference< XInterface > SAL_CALL ImplIntrospection_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr )
2861 : throw( RuntimeException )
2862 : {
2863 66 : Reference< XInterface > xService = (OWeakObject*)(OComponentHelper*)new ImplIntrospection( rSMgr );
2864 66 : return xService;
2865 : }
2866 :
2867 : }
2868 :
2869 : extern "C"
2870 : {
2871 66 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL introspection_component_getFactory(
2872 : const sal_Char * pImplName, void * pServiceManager,
2873 : SAL_UNUSED_PARAMETER void * )
2874 : {
2875 66 : void * pRet = 0;
2876 :
2877 66 : if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
2878 : {
2879 : Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory(
2880 : reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
2881 : OUString::createFromAscii( pImplName ),
2882 : stoc_inspect::ImplIntrospection_CreateInstance,
2883 66 : stoc_inspect::ImplIntrospection::getSupportedServiceNames_Static() ) );
2884 :
2885 66 : if (xFactory.is())
2886 : {
2887 66 : xFactory->acquire();
2888 66 : pRet = xFactory.get();
2889 66 : }
2890 : }
2891 :
2892 66 : return pRet;
2893 : }
2894 : }
2895 :
2896 :
2897 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|