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