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