merge the formfield patch from ooo-build
[ooovba.git] / stoc / source / inspect / introspection.cxx
blob33b7e92139f50c390eb120e3f7a83cc9c8fc202b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: introspection.cxx,v $
10 * $Revision: 1.25 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_stoc.hxx"
34 #include <string.h>
36 // Schalter fuer Introspection-Caching
37 #ifndef OS2
38 #define USE_INTROSPECTION_CACHE
39 #endif
41 #ifdef USE_INTROSPECTION_CACHE
42 #define INTROSPECTION_CACHE_MAX_SIZE 100
43 #endif
44 #include <osl/diagnose.h>
45 #include <osl/mutex.hxx>
46 #include <osl/thread.h>
47 #include <cppuhelper/queryinterface.hxx>
48 #include <cppuhelper/weak.hxx>
49 #include <cppuhelper/component.hxx>
50 #include <cppuhelper/factory.hxx>
51 #include <cppuhelper/implbase3.hxx>
52 #include <cppuhelper/typeprovider.hxx>
54 #include <com/sun/star/uno/DeploymentException.hpp>
55 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
56 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
57 #include <com/sun/star/lang/XServiceInfo.hpp>
58 #include <com/sun/star/lang/XEventListener.hpp>
59 #include <com/sun/star/reflection/XIdlReflection.hpp>
60 #include <com/sun/star/reflection/XIdlClassProvider.hpp>
61 #include <com/sun/star/reflection/XIdlClass.hpp>
62 #include <com/sun/star/reflection/XIdlField2.hpp>
63 #include <com/sun/star/beans/UnknownPropertyException.hpp>
64 #include <com/sun/star/beans/Property.hpp>
65 #include <com/sun/star/beans/XPropertySet.hpp>
66 #include <com/sun/star/beans/XFastPropertySet.hpp>
67 #include <com/sun/star/beans/XIntrospection.hpp>
68 #include <com/sun/star/beans/XIntrospectionAccess.hpp>
69 #include <com/sun/star/beans/XMaterialHolder.hpp>
70 #include <com/sun/star/beans/XExactName.hpp>
71 #include <com/sun/star/beans/PropertyAttribute.hpp>
72 #include <com/sun/star/beans/PropertyConcept.hpp>
73 #include <com/sun/star/beans/MethodConcept.hpp>
74 #include <com/sun/star/container/XNameContainer.hpp>
75 #include <com/sun/star/container/XIndexContainer.hpp>
76 #include <com/sun/star/container/XEnumerationAccess.hpp>
77 #include <com/sun/star/registry/XRegistryKey.hpp>
79 #include <rtl/ustrbuf.hxx>
80 #include <rtl/strbuf.hxx>
81 #include <hash_map>
83 using namespace com::sun::star::uno;
84 using namespace com::sun::star::lang;
85 using namespace com::sun::star::reflection;
86 using namespace com::sun::star::container;
87 using namespace com::sun::star::registry;
88 using namespace com::sun::star::beans;
89 using namespace com::sun::star::beans::PropertyAttribute;
90 using namespace com::sun::star::beans::PropertyConcept;
91 using namespace com::sun::star::beans::MethodConcept;
92 using namespace cppu;
93 using namespace osl;
94 using namespace rtl;
96 #define IMPLEMENTATION_NAME "com.sun.star.comp.stoc.Introspection"
97 #define SERVICE_NAME "com.sun.star.beans.Introspection"
99 namespace stoc_inspect
102 typedef WeakImplHelper3< XIntrospectionAccess, XMaterialHolder, XExactName > IntrospectionAccessHelper;
105 //==================================================================================================
107 // Spezial-Wert fuer Method-Concept, um "normale" Funktionen kennzeichnen zu koennen
108 #define MethodConcept_NORMAL_IMPL 0x80000000
111 // Methode zur Feststellung, ob eine Klasse von einer anderen abgeleitet ist
112 sal_Bool isDerivedFrom( Reference<XIdlClass> xToTestClass, Reference<XIdlClass> xDerivedFromClass )
114 Sequence< Reference<XIdlClass> > aClassesSeq = xToTestClass->getSuperclasses();
115 const Reference<XIdlClass>* pClassesArray = aClassesSeq.getConstArray();
116 sal_Int32 nSuperClassCount = aClassesSeq.getLength();
117 sal_Int32 i;
118 for( i = 0 ; i < nSuperClassCount ; i++ )
120 const Reference<XIdlClass>& rxClass = pClassesArray[i];
121 if( xDerivedFromClass->equals( rxClass ) )
123 // Treffer
124 return sal_True;
126 else
128 // Rekursiv weitersuchen
129 return isDerivedFrom( rxClass, xDerivedFromClass );
132 return sal_False;
135 //========================================================================
137 // *** Klassifizierung der Properties (kein enum, um Sequence verwenden zu koennen) ***
138 // Properties aus einem PropertySet-Interface
139 #define MAP_PROPERTY_SET 0
140 // Properties aus Fields
141 #define MAP_FIELD 1
142 // Properties, die durch get/set-Methoden beschrieben werden
143 #define MAP_GETSET 2
144 // Properties, die nur eine set-Methode haben
145 #define MAP_SETONLY 3
148 // Schrittweite, in der die Groesse der Sequences angepasst wird
149 #define ARRAY_SIZE_STEP 20
153 //**************************************
154 //*** IntrospectionAccessStatic_Impl ***
155 //**************************************
156 // Entspricht dem alten IntrospectionAccessImpl, bildet jetzt den statischen
157 // Anteil des neuen Instanz-bezogenen ImplIntrospectionAccess
159 // ACHTUNG !!! Von Hand refcounten !!!
162 // Hashtable fuer die Suche nach Namen
163 struct hashName_Impl
165 size_t operator()(const OUString Str) const
167 return (size_t)Str.hashCode();
171 struct eqName_Impl
173 sal_Bool operator()(const OUString Str1, const OUString Str2) const
175 return ( Str1 == Str2 );
179 typedef std::hash_map
181 OUString,
182 sal_Int32,
183 hashName_Impl,
184 eqName_Impl
186 IntrospectionNameMap;
189 // Hashtable zur Zuordnung der exakten Namen zu den zu Lower-Case
190 // konvertierten Namen, dient zur Unterst�tzung von XExactName
191 typedef std::hash_map
193 OUString,
194 OUString,
195 hashName_Impl,
196 eqName_Impl
198 LowerToExactNameMap;
201 class ImplIntrospectionAccess;
202 class IntrospectionAccessStatic_Impl
204 friend class ImplIntrospection;
205 friend class ImplIntrospectionAccess;
207 // CoreReflection halten
208 Reference< XIdlReflection > mxCoreReflection;
210 // InterfaceSequences, um Zusatz-Infos zu einer Property speichern zu koennen.
211 // z.B. das Field bei MAP_FIELD, die get/set-Methoden bei MAP_GETSET usw.
212 Sequence< Reference<XInterface> > aInterfaceSeq1;
213 Sequence< Reference<XInterface> > aInterfaceSeq2;
215 // Hashtables fuer die Namen
216 IntrospectionNameMap maPropertyNameMap;
217 IntrospectionNameMap maMethodNameMap;
218 LowerToExactNameMap maLowerToExactNameMap;
220 // Sequence aller Properties, auch zum Liefern aus getProperties()
221 Sequence<Property> maAllPropertySeq;
223 // Mapping der Properties auf Zugriffs-Arten
224 Sequence<sal_Int16> maMapTypeSeq;
226 // Klassifizierung der gefundenen Methoden
227 Sequence<sal_Int32> maPropertyConceptSeq;
229 // Anzahl der Properties
230 sal_Int32 mnPropCount;
232 // Anzahl der Properties, die den jeweiligen Konzepten zugeordnet sind
233 //sal_Int32 mnDangerousPropCount;
234 sal_Int32 mnPropertySetPropCount;
235 sal_Int32 mnAttributePropCount;
236 sal_Int32 mnMethodPropCount;
238 // Flag, ob ein FastPropertySet unterstuetzt wird
239 sal_Bool mbFastPropSet;
241 // Original-Handles eines FastPropertySets
242 sal_Int32* mpOrgPropertyHandleArray;
244 // MethodSequence, die alle Methoden aufnimmt
245 Sequence< Reference<XIdlMethod> > maAllMethodSeq;
247 // Klassifizierung der gefundenen Methoden
248 Sequence<sal_Int32> maMethodConceptSeq;
250 // Anzahl der Methoden
251 sal_Int32 mnMethCount;
253 // Sequence der Listener, die angemeldet werden koennen
254 Sequence< Type > maSupportedListenerSeq;
256 // BaseInit (soll spaeter in der Applikation erfolgen!)
257 void BaseInit( void );
259 // Hilfs-Methoden zur Groessen-Anpassung der Sequences
260 void checkPropertyArraysSize
262 Property*& rpAllPropArray,
263 sal_Int16*& rpMapTypeArray,
264 sal_Int32*& rpPropertyConceptArray,
265 sal_Int32 iNextIndex
267 void checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq, Reference<XInterface>*& rpInterfaceArray,
268 sal_Int32 iNextIndex );
270 // RefCount
271 sal_Int32 nRefCount;
274 public:
275 IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ );
276 ~IntrospectionAccessStatic_Impl()
278 delete[] mpOrgPropertyHandleArray;
280 sal_Int32 getPropertyIndex( const OUString& aPropertyName ) const;
281 sal_Int32 getMethodIndex( const OUString& aMethodName ) const;
283 void acquire() { nRefCount++; }
284 void release()
286 nRefCount--;
287 if( nRefCount <= 0 )
288 delete this;
291 // Methoden von XIntrospectionAccess (ALT, jetzt nur Impl)
292 void setPropertyValue(const Any& obj, const OUString& aPropertyName, const Any& aValue) const;
293 // void setPropertyValue(Any& obj, const OUString& aPropertyName, const Any& aValue) const;
294 Any getPropertyValue(const Any& obj, const OUString& aPropertyName) const;
295 void setPropertyValueByIndex(const Any& obj, sal_Int32 nIndex, const Any& aValue) const;
296 // void setPropertyValueByIndex(Any& obj, sal_Int32 nIndex, const Any& aValue) const;
297 Any getPropertyValueByIndex(const Any& obj, sal_Int32 nIndex) const;
299 Sequence<Property> getProperties(void) const { return maAllPropertySeq; }
300 Sequence< Reference<XIdlMethod> > getMethods(void) const { return maAllMethodSeq; }
301 Sequence< Type > getSupportedListeners(void) const { return maSupportedListenerSeq; }
302 Sequence<sal_Int32> getPropertyConcepts(void) const { return maPropertyConceptSeq; }
303 Sequence<sal_Int32> getMethodConcepts(void) const { return maMethodConceptSeq; }
307 // Ctor
308 IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ )
309 : mxCoreReflection( xCoreReflection_ )
311 aInterfaceSeq1.realloc( ARRAY_SIZE_STEP );
312 aInterfaceSeq2.realloc( ARRAY_SIZE_STEP );
314 // Property-Daten
315 maAllPropertySeq.realloc( ARRAY_SIZE_STEP );
316 maMapTypeSeq.realloc( ARRAY_SIZE_STEP );
317 maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP );
319 mbFastPropSet = sal_False;
320 mpOrgPropertyHandleArray = NULL;
322 mnPropCount = 0;
323 //mnDangerousPropCount = 0;
324 mnPropertySetPropCount = 0;
325 mnAttributePropCount = 0;
326 mnMethodPropCount = 0;
328 // Method-Daten
329 mnMethCount = 0;
331 // Eigenens RefCounting
332 nRefCount = 0;
335 // Von Hand refcounten !!!
338 sal_Int32 IntrospectionAccessStatic_Impl::getPropertyIndex( const OUString& aPropertyName ) const
340 sal_Int32 iHashResult = -1;
341 IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
342 IntrospectionNameMap::iterator aIt = pThis->maPropertyNameMap.find( aPropertyName );
343 if( !( aIt == pThis->maPropertyNameMap.end() ) )
344 iHashResult = (*aIt).second;
345 return iHashResult;
348 sal_Int32 IntrospectionAccessStatic_Impl::getMethodIndex( const OUString& aMethodName ) const
350 sal_Int32 iHashResult = -1;
351 IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
352 IntrospectionNameMap::iterator aIt = pThis->maMethodNameMap.find( aMethodName );
353 if( !( aIt == pThis->maMethodNameMap.end() ) )
355 iHashResult = (*aIt).second;
357 // #95159 Check if full qualified name matches
358 else
360 sal_Int32 nSearchFrom = aMethodName.getLength();
361 nSearchFrom = aMethodName.getLength();
362 while( true )
364 // Strategy: Search back until the first '_' is found
365 sal_Int32 nFound = aMethodName.lastIndexOf( '_', nSearchFrom );
366 if( nFound == -1 )
367 break;
369 OUString aPureMethodName = aMethodName.copy( nFound + 1 );
371 aIt = pThis->maMethodNameMap.find( aPureMethodName );
372 if( !( aIt == pThis->maMethodNameMap.end() ) )
374 // Check if it can be a type?
375 // Problem: Does not work if package names contain _ ?!
376 OUString aStr = aMethodName.copy( 0, nFound );
377 OUString aTypeName = aStr.replace( '_', '.' );
378 Reference< XIdlClass > xClass = mxCoreReflection->forName( aTypeName );
379 if( xClass.is() )
381 // If this is a valid class it could be the right method
383 // Could be the right method, type has to be checked
384 iHashResult = (*aIt).second;
386 const Reference<XIdlMethod>* pMethods = maAllMethodSeq.getConstArray();
387 const Reference<XIdlMethod> xMethod = pMethods[ iHashResult ];
389 Reference< XIdlClass > xMethClass = xMethod->getDeclaringClass();
390 if( xClass->equals( xMethClass ) )
392 break;
394 else
396 iHashResult = -1;
398 // Could also be another method with the same name
399 // Iterate over all methods
400 sal_Int32 nLen = maAllMethodSeq.getLength();
401 for( int i = 0 ; i < nLen ; ++i )
403 const Reference<XIdlMethod> xMethod2 = pMethods[ i ];
405 OUString aTestClassName = xMethod2->getDeclaringClass()->getName();
406 OUString aTestMethodName = xMethod2->getName();
408 if( xMethod2->getName() == aPureMethodName )
410 Reference< XIdlClass > xMethClass2 = xMethod2->getDeclaringClass();
412 if( xClass->equals( xMethClass2 ) )
414 iHashResult = i;
415 break;
420 if( iHashResult != -1 )
421 break;
426 nSearchFrom = nFound - 1;
427 if( nSearchFrom < 0 )
428 break;
431 return iHashResult;
434 void IntrospectionAccessStatic_Impl::setPropertyValue( const Any& obj, const OUString& aPropertyName, const Any& aValue ) const
435 //void IntrospectionAccessStatic_Impl::setPropertyValue( Any& obj, const OUString& aPropertyName, const Any& aValue ) const
437 sal_Int32 i = getPropertyIndex( aPropertyName );
438 if( i != -1 )
439 setPropertyValueByIndex( obj, (sal_Int32)i, aValue );
440 else
441 throw UnknownPropertyException();
444 void IntrospectionAccessStatic_Impl::setPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
445 //void IntrospectionAccessStatic_Impl::setPropertyValueByIndex( Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
447 // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes?
448 TypeClass eObjType = obj.getValueType().getTypeClass();
450 Reference<XInterface> xInterface;
451 if( eObjType == TypeClass_INTERFACE )
453 xInterface = *( Reference<XInterface>*)obj.getValue();
455 else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
457 throw IllegalArgumentException();
460 // Flags pruefen
461 const Property* pProps = maAllPropertySeq.getConstArray();
462 if( (pProps[ nSequenceIndex ].Attributes & READONLY) != 0 )
464 throw UnknownPropertyException();
467 const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
468 switch( pMapTypeArray[ nSequenceIndex ] )
470 case MAP_PROPERTY_SET:
472 // Property besorgen
473 const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
475 // Interface-Parameter auf den richtigen Typ bringen
476 sal_Bool bUseCopy = sal_False;
477 Any aRealValue;
479 TypeClass eValType = aValue.getValueType().getTypeClass();
480 if( eValType == TypeClass_INTERFACE )
482 Type aPropType = rProp.Type;
483 OUString aTypeName( aPropType.getTypeName() );
484 Reference< XIdlClass > xPropClass = mxCoreReflection->forName( aTypeName );
485 //Reference<XIdlClass> xPropClass = rProp.Type;
486 if( xPropClass.is() && xPropClass->getTypeClass() == TypeClass_INTERFACE )
488 Reference<XInterface> valInterface = *(Reference<XInterface>*)aValue.getValue();
489 if( valInterface.is() )
491 //Any queryInterface( const Type& rType );
492 aRealValue = valInterface->queryInterface( aPropType );
493 if( aRealValue.hasValue() )
494 bUseCopy = sal_True;
499 // Haben wir ein FastPropertySet und ein gueltiges Handle?
500 // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet
501 // zu Beginn des Introspection-Vorgangs abgefragt wird.
502 sal_Int32 nOrgHandle;
503 if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
505 // PropertySet-Interface holen
506 Reference<XFastPropertySet> xFastPropSet =
507 Reference<XFastPropertySet>::query( xInterface );
508 if( xFastPropSet.is() )
510 xFastPropSet->setFastPropertyValue( nOrgHandle, bUseCopy ? aRealValue : aValue );
512 else
514 // throw UnknownPropertyException
517 // sonst eben das normale nehmen
518 else
520 // PropertySet-Interface holen
521 Reference<XPropertySet> xPropSet =
522 Reference<XPropertySet>::query( xInterface );
523 if( xPropSet.is() )
525 xPropSet->setPropertyValue( rProp.Name, bUseCopy ? aRealValue : aValue );
527 else
529 // throw UnknownPropertyException
533 break;
535 case MAP_FIELD:
537 Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
538 Reference<XIdlField2> xField2(xField, UNO_QUERY);
539 if( xField2.is() )
541 xField2->set( (Any&)obj, aValue );
542 // IllegalArgumentException
543 // NullPointerException
544 } else
545 if( xField.is() )
547 xField->set( obj, aValue );
548 // IllegalArgumentException
549 // NullPointerException
551 else
553 // throw IllegalArgumentException();
556 break;
558 case MAP_GETSET:
559 case MAP_SETONLY:
561 // set-Methode holen
562 Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq2.getConstArray()[ nSequenceIndex ].get());
563 if( xMethod.is() )
565 Sequence<Any> args( 1 );
566 args.getArray()[0] = aValue;
567 xMethod->invoke( obj, args );
569 else
571 // throw IllegalArgumentException();
574 break;
578 Any IntrospectionAccessStatic_Impl::getPropertyValue( const Any& obj, const OUString& aPropertyName ) const
580 sal_Int32 i = getPropertyIndex( aPropertyName );
581 if( i != -1 )
582 return getPropertyValueByIndex( obj, i );
584 throw UnknownPropertyException();
587 Any IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex) const
589 Any aRet;
591 // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes?
592 TypeClass eObjType = obj.getValueType().getTypeClass();
594 Reference<XInterface> xInterface;
595 if( eObjType == TypeClass_INTERFACE )
597 xInterface = *(Reference<XInterface>*)obj.getValue();
599 else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
601 // throw IllegalArgumentException();
602 return aRet;
605 const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
606 switch( pMapTypeArray[ nSequenceIndex ] )
608 case MAP_PROPERTY_SET:
610 // Property besorgen
611 const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
613 // Haben wir ein FastPropertySet und ein gueltiges Handle?
614 // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet
615 // zu Beginn des Introspection-Vorgangs abgefragt wird.
616 sal_Int32 nOrgHandle;
617 if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
619 // PropertySet-Interface holen
620 Reference<XFastPropertySet> xFastPropSet =
621 Reference<XFastPropertySet>::query( xInterface );
622 if( xFastPropSet.is() )
624 aRet = xFastPropSet->getFastPropertyValue( nOrgHandle);
626 else
628 // throw UnknownPropertyException
629 return aRet;
632 // sonst eben das normale nehmen
633 else
635 // PropertySet-Interface holen
636 Reference<XPropertySet> xPropSet =
637 Reference<XPropertySet>::query( xInterface );
638 if( xPropSet.is() )
640 aRet = xPropSet->getPropertyValue( rProp.Name );
642 else
644 // throw UnknownPropertyException
645 return aRet;
649 break;
651 case MAP_FIELD:
653 Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
654 if( xField.is() )
656 aRet = xField->get( obj );
657 // IllegalArgumentException
658 // NullPointerException
660 else
662 // throw IllegalArgumentException();
663 return aRet;
666 break;
668 case MAP_GETSET:
670 // get-Methode holen
671 Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
672 if( xMethod.is() )
674 Sequence<Any> args;
675 aRet = xMethod->invoke( obj, args );
677 else
679 // throw IllegalArgumentException();
680 return aRet;
683 break;
685 case MAP_SETONLY:
686 // get-Methode gibt es nicht
687 // throw WriteOnlyPropertyException();
688 return aRet;
690 return aRet;
694 // Hilfs-Methoden zur Groessen-Anpassung der Sequences
695 void IntrospectionAccessStatic_Impl::checkPropertyArraysSize
697 Property*& rpAllPropArray,
698 sal_Int16*& rpMapTypeArray,
699 sal_Int32*& rpPropertyConceptArray,
700 sal_Int32 iNextIndex
703 sal_Int32 nLen = maAllPropertySeq.getLength();
704 if( iNextIndex >= nLen )
706 maAllPropertySeq.realloc( nLen + ARRAY_SIZE_STEP );
707 rpAllPropArray = maAllPropertySeq.getArray();
709 maMapTypeSeq.realloc( nLen + ARRAY_SIZE_STEP );
710 rpMapTypeArray = maMapTypeSeq.getArray();
712 maPropertyConceptSeq.realloc( nLen + ARRAY_SIZE_STEP );
713 rpPropertyConceptArray = maPropertyConceptSeq.getArray();
717 void IntrospectionAccessStatic_Impl::checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq,
718 Reference<XInterface>*& rpInterfaceArray, sal_Int32 iNextIndex )
720 sal_Int32 nLen = rSeq.getLength();
721 if( iNextIndex >= nLen )
723 // Neue Groesse mit ARRAY_SIZE_STEP abgleichen
724 sal_Int32 nMissingSize = iNextIndex - nLen + 1;
725 sal_Int32 nSteps = nMissingSize / ARRAY_SIZE_STEP + 1;
726 sal_Int32 nNewSize = nLen + nSteps * ARRAY_SIZE_STEP;
728 rSeq.realloc( nNewSize );
729 rpInterfaceArray = rSeq.getArray();
734 //*******************************
735 //*** ImplIntrospectionAdapter ***
736 //*******************************
738 // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
739 // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
740 // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
741 class ImplIntrospectionAdapter :
742 public XPropertySet, public XFastPropertySet, public XPropertySetInfo,
743 public XNameContainer, public XIndexContainer,
744 public XEnumerationAccess, public XIdlArray,
745 public OWeakObject
747 // Parent-Objekt
748 ImplIntrospectionAccess* mpAccess;
750 // Untersuchtes Objekt
751 const Any& mrInspectedObject;
753 // Statische Daten der Introspection
754 IntrospectionAccessStatic_Impl* mpStaticImpl;
756 // Objekt als Interface
757 Reference<XInterface> mxIface;
759 // Original-Interfaces des Objekts
760 Reference<XElementAccess> mxObjElementAccess;
761 Reference<XNameContainer> mxObjNameContainer;
762 Reference<XNameAccess> mxObjNameAccess;
763 Reference<XIndexAccess> mxObjIndexAccess;
764 Reference<XIndexContainer> mxObjIndexContainer;
765 Reference<XEnumerationAccess> mxObjEnumerationAccess;
766 Reference<XIdlArray> mxObjIdlArray;
768 public:
769 ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
770 const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ );
771 ~ImplIntrospectionAdapter();
773 // Methoden von XInterface
774 virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
775 virtual void SAL_CALL acquire() throw() { OWeakObject::acquire(); }
776 virtual void SAL_CALL release() throw() { OWeakObject::release(); }
778 // Methoden von XPropertySet
779 virtual Reference<XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( RuntimeException );
780 virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName, const Any& aValue)
781 throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException );
782 virtual Any SAL_CALL getPropertyValue(const OUString& aPropertyName)
783 throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
784 virtual void SAL_CALL addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
785 throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
786 virtual void SAL_CALL removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
787 throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
788 virtual void SAL_CALL addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
789 throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
790 virtual void SAL_CALL removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
791 throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
793 // Methoden von XFastPropertySet
794 virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const Any& aValue)
795 throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException );
796 virtual Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle)
797 throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
799 // Methoden von XPropertySetInfo
800 virtual Sequence< Property > SAL_CALL getProperties(void) throw( RuntimeException );
801 virtual Property SAL_CALL getPropertyByName(const OUString& Name) throw( RuntimeException );
802 virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& Name) throw( RuntimeException );
804 // Methoden von XElementAccess
805 virtual Type SAL_CALL getElementType(void) throw( RuntimeException );
806 virtual sal_Bool SAL_CALL hasElements(void) throw( RuntimeException );
808 // Methoden von XNameAccess
809 virtual Any SAL_CALL getByName(const OUString& Name)
810 throw( NoSuchElementException, WrappedTargetException, RuntimeException );
811 virtual Sequence<OUString> SAL_CALL getElementNames(void) throw( RuntimeException );
812 virtual sal_Bool SAL_CALL hasByName(const OUString& Name) throw( RuntimeException );
814 // Methoden von XNameContainer
815 virtual void SAL_CALL insertByName(const OUString& Name, const Any& Element)
816 throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException );
817 virtual void SAL_CALL replaceByName(const OUString& Name, const Any& Element)
818 throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException );
819 virtual void SAL_CALL removeByName(const OUString& Name)
820 throw( NoSuchElementException, WrappedTargetException, RuntimeException );
822 // Methoden von XIndexAccess
823 virtual sal_Int32 SAL_CALL getCount(void) throw( RuntimeException );
824 virtual Any SAL_CALL getByIndex(sal_Int32 Index)
825 throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
827 // Methoden von XIndexContainer
828 virtual void SAL_CALL insertByIndex(sal_Int32 Index, const Any& Element)
829 throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
830 virtual void SAL_CALL replaceByIndex(sal_Int32 Index, const Any& Element)
831 throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
832 virtual void SAL_CALL removeByIndex(sal_Int32 Index)
833 throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
835 // Methoden von XEnumerationAccess
836 virtual Reference<XEnumeration> SAL_CALL createEnumeration(void) throw( RuntimeException );
838 // Methoden von XIdlArray
839 virtual void SAL_CALL realloc(Any& array, sal_Int32 length)
840 throw( IllegalArgumentException, RuntimeException );
841 virtual sal_Int32 SAL_CALL getLen(const Any& array) throw( IllegalArgumentException, RuntimeException );
842 virtual Any SAL_CALL get(const Any& array, sal_Int32 index)
843 throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException );
844 virtual void SAL_CALL set(Any& array, sal_Int32 index, const Any& value)
845 throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException );
848 ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
849 const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ )
850 : mpAccess( pAccess_), mrInspectedObject( obj ), mpStaticImpl( pStaticImpl_ )
852 mpStaticImpl->acquire();
854 // Objekt als Interfaceholen
855 TypeClass eType = mrInspectedObject.getValueType().getTypeClass();
856 if( eType == TypeClass_INTERFACE )
858 mxIface = *( Reference< XInterface >*)mrInspectedObject.getValue();
860 mxObjElementAccess = Reference<XElementAccess>::query( mxIface );
861 mxObjNameAccess = Reference<XNameAccess>::query( mxIface );
862 mxObjNameContainer = Reference<XNameContainer>::query( mxIface );
863 mxObjIndexAccess = Reference<XIndexAccess>::query( mxIface );
864 mxObjIndexContainer = Reference<XIndexContainer>::query( mxIface );
865 mxObjEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface );
866 mxObjIdlArray = Reference<XIdlArray>::query( mxIface );
870 ImplIntrospectionAdapter::~ImplIntrospectionAdapter()
872 mpStaticImpl->release();
875 // Methoden von XInterface
876 Any SAL_CALL ImplIntrospectionAdapter::queryInterface( const Type& rType )
877 throw( RuntimeException )
879 Any aRet( ::cppu::queryInterface(
880 rType,
881 static_cast< XPropertySet * >( this ),
882 static_cast< XFastPropertySet * >( this ),
883 static_cast< XPropertySetInfo * >( this ) ) );
884 if( !aRet.hasValue() )
885 aRet = OWeakObject::queryInterface( rType );
887 if( !aRet.hasValue() )
889 // Wrapper fuer die Objekt-Interfaces
890 if( ( mxObjElementAccess.is() && (aRet = ::cppu::queryInterface
891 ( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() )
892 || ( mxObjNameAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() )
893 || ( mxObjNameContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() )
894 || ( mxObjIndexAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() )
895 || ( mxObjIndexContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() )
896 || ( mxObjEnumerationAccess .is() && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() )
897 || ( mxObjIdlArray.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() )
902 return aRet;
906 //*******************************
907 //*** ImplIntrospectionAccess ***
908 //*******************************
910 // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
911 // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
912 // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
913 class ImplIntrospectionAccess : IntrospectionAccessHelper
915 friend class ImplIntrospection;
917 // Untersuchtes Objekt
918 Any maInspectedObject;
920 // Als Interface
921 Reference<XInterface> mxIface;
923 // Statische Daten der Introspection
924 IntrospectionAccessStatic_Impl* mpStaticImpl;
926 // Adapter-Implementation
927 ImplIntrospectionAdapter* mpAdapter;
929 // Letzte Sequence, die bei getProperties geliefert wurde (Optimierung)
930 Sequence<Property> maLastPropertySeq;
931 sal_Int32 mnLastPropertyConcept;
933 // Letzte Sequence, die bei getMethods geliefert wurde (Optimierung)
934 Sequence<Reference<XIdlMethod> > maLastMethodSeq;
935 sal_Int32 mnLastMethodConcept;
937 public:
938 ImplIntrospectionAccess( const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ );
939 ~ImplIntrospectionAccess();
941 // Methoden von XIntrospectionAccess
942 virtual sal_Int32 SAL_CALL getSuppliedMethodConcepts(void)
943 throw( RuntimeException );
944 virtual sal_Int32 SAL_CALL getSuppliedPropertyConcepts(void)
945 throw( RuntimeException );
946 virtual Property SAL_CALL getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
947 throw( NoSuchElementException, RuntimeException );
948 virtual sal_Bool SAL_CALL hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
949 throw( RuntimeException );
950 virtual Sequence< Property > SAL_CALL getProperties(sal_Int32 PropertyConcepts)
951 throw( RuntimeException );
952 virtual Reference<XIdlMethod> SAL_CALL getMethod(const OUString& Name, sal_Int32 MethodConcepts)
953 throw( NoSuchMethodException, RuntimeException );
954 virtual sal_Bool SAL_CALL hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
955 throw( RuntimeException );
956 virtual Sequence< Reference<XIdlMethod> > SAL_CALL getMethods(sal_Int32 MethodConcepts)
957 throw( RuntimeException );
958 virtual Sequence< Type > SAL_CALL getSupportedListeners(void)
959 throw( RuntimeException );
960 using OWeakObject::queryAdapter;
961 virtual Reference<XInterface> SAL_CALL queryAdapter( const Type& rType )
962 throw( IllegalTypeException, RuntimeException );
964 // Methoden von XMaterialHolder
965 virtual Any SAL_CALL getMaterial(void) throw(RuntimeException);
967 // Methoden von XExactName
968 virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) throw( RuntimeException );
971 ImplIntrospectionAccess::ImplIntrospectionAccess
972 ( const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ )
973 : maInspectedObject( obj ), mpStaticImpl( pStaticImpl_ ), mpAdapter( NULL )
975 mpStaticImpl->acquire();
977 // Objekt als Interface merken, wenn moeglich
978 TypeClass eType = maInspectedObject.getValueType().getTypeClass();
979 if( eType == TypeClass_INTERFACE )
980 mxIface = *(Reference<XInterface>*)maInspectedObject.getValue();
982 mnLastPropertyConcept = -1;
983 mnLastMethodConcept = -1;
986 ImplIntrospectionAccess::~ImplIntrospectionAccess()
988 mpStaticImpl->release();
990 // Eigene Referenz loslassen
991 if (mpAdapter)
992 mpAdapter->release();
996 //***************************************************
997 //*** Implementation von ImplIntrospectionAdapter ***
998 //***************************************************
1000 // Methoden von XPropertySet
1001 Reference<XPropertySetInfo> ImplIntrospectionAdapter::getPropertySetInfo(void)
1002 throw( RuntimeException )
1004 return (XPropertySetInfo *)this;
1007 void ImplIntrospectionAdapter::setPropertyValue(const OUString& aPropertyName, const Any& aValue)
1008 throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
1010 mpStaticImpl->setPropertyValue( mrInspectedObject, aPropertyName, aValue );
1013 Any ImplIntrospectionAdapter::getPropertyValue(const OUString& aPropertyName)
1014 throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
1016 return mpStaticImpl->getPropertyValue( mrInspectedObject, aPropertyName );
1019 void ImplIntrospectionAdapter::addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
1020 throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
1022 if( mxIface.is() )
1024 Reference<XPropertySet> xPropSet =
1025 Reference<XPropertySet>::query( mxIface );
1026 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
1027 if( xPropSet.is() )
1028 xPropSet->addPropertyChangeListener(aPropertyName, aListener);
1032 void ImplIntrospectionAdapter::removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
1033 throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
1035 if( mxIface.is() )
1037 Reference<XPropertySet> xPropSet =
1038 Reference<XPropertySet>::query( mxIface );
1039 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
1040 if( xPropSet.is() )
1041 xPropSet->removePropertyChangeListener(aPropertyName, aListener);
1045 void ImplIntrospectionAdapter::addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
1046 throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
1048 if( mxIface.is() )
1050 Reference<XPropertySet> xPropSet =
1051 Reference<XPropertySet>::query( mxIface );
1052 //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
1053 if( xPropSet.is() )
1054 xPropSet->addVetoableChangeListener(aPropertyName, aListener);
1058 void ImplIntrospectionAdapter::removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
1059 throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
1061 if( mxIface.is() )
1063 Reference<XPropertySet> xPropSet =
1064 Reference<XPropertySet>::query( mxIface );
1065 if( xPropSet.is() )
1066 xPropSet->removeVetoableChangeListener(aPropertyName, aListener);
1071 // Methoden von XFastPropertySet
1072 void ImplIntrospectionAdapter::setFastPropertyValue(sal_Int32, const Any&)
1073 throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
1077 Any ImplIntrospectionAdapter::getFastPropertyValue(sal_Int32)
1078 throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
1080 return Any();
1083 // Methoden von XPropertySetInfo
1084 Sequence< Property > ImplIntrospectionAdapter::getProperties(void) throw( RuntimeException )
1086 return mpStaticImpl->getProperties();
1089 Property ImplIntrospectionAdapter::getPropertyByName(const OUString& Name)
1090 throw( RuntimeException )
1092 return mpAccess->getProperty( Name, PropertyConcept::ALL );
1095 sal_Bool ImplIntrospectionAdapter::hasPropertyByName(const OUString& Name)
1096 throw( RuntimeException )
1098 return mpAccess->hasProperty( Name, PropertyConcept::ALL );
1101 // Methoden von XElementAccess
1102 Type ImplIntrospectionAdapter::getElementType(void) throw( RuntimeException )
1104 return mxObjElementAccess->getElementType();
1107 sal_Bool ImplIntrospectionAdapter::hasElements(void) throw( RuntimeException )
1109 return mxObjElementAccess->hasElements();
1112 // Methoden von XNameAccess
1113 Any ImplIntrospectionAdapter::getByName(const OUString& Name)
1114 throw( NoSuchElementException, WrappedTargetException, RuntimeException )
1116 return mxObjNameAccess->getByName( Name );
1119 Sequence< OUString > ImplIntrospectionAdapter::getElementNames(void)
1120 throw( RuntimeException )
1122 return mxObjNameAccess->getElementNames();
1125 sal_Bool ImplIntrospectionAdapter::hasByName(const OUString& Name)
1126 throw( RuntimeException )
1128 return mxObjNameAccess->hasByName( Name );
1131 // Methoden von XNameContainer
1132 void ImplIntrospectionAdapter::insertByName(const OUString& Name, const Any& Element)
1133 throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
1135 mxObjNameContainer->insertByName( Name, Element );
1138 void ImplIntrospectionAdapter::replaceByName(const OUString& Name, const Any& Element)
1139 throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
1141 mxObjNameContainer->replaceByName( Name, Element );
1144 void ImplIntrospectionAdapter::removeByName(const OUString& Name)
1145 throw( NoSuchElementException, WrappedTargetException, RuntimeException )
1147 mxObjNameContainer->removeByName( Name );
1150 // Methoden von XIndexAccess
1151 // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const
1152 sal_Int32 ImplIntrospectionAdapter::getCount(void) throw( RuntimeException )
1154 return mxObjIndexAccess->getCount();
1157 Any ImplIntrospectionAdapter::getByIndex(sal_Int32 Index)
1158 throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1160 return mxObjIndexAccess->getByIndex( Index );
1163 // Methoden von XIndexContainer
1164 void ImplIntrospectionAdapter::insertByIndex(sal_Int32 Index, const Any& Element)
1165 throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1167 mxObjIndexContainer->insertByIndex( Index, Element );
1170 void ImplIntrospectionAdapter::replaceByIndex(sal_Int32 Index, const Any& Element)
1171 throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1173 mxObjIndexContainer->replaceByIndex( Index, Element );
1176 void ImplIntrospectionAdapter::removeByIndex(sal_Int32 Index)
1177 throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1179 mxObjIndexContainer->removeByIndex( Index );
1182 // Methoden von XEnumerationAccess
1183 // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const;
1184 Reference<XEnumeration> ImplIntrospectionAdapter::createEnumeration(void) throw( RuntimeException )
1186 return mxObjEnumerationAccess->createEnumeration();
1189 // Methoden von XIdlArray
1190 void ImplIntrospectionAdapter::realloc(Any& array, sal_Int32 length)
1191 throw( IllegalArgumentException, RuntimeException )
1193 mxObjIdlArray->realloc( array, length );
1196 sal_Int32 ImplIntrospectionAdapter::getLen(const Any& array)
1197 throw( IllegalArgumentException, RuntimeException )
1199 return mxObjIdlArray->getLen( array );
1202 Any ImplIntrospectionAdapter::get(const Any& array, sal_Int32 index)
1203 throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException )
1205 return mxObjIdlArray->get( array, index );
1208 void ImplIntrospectionAdapter::set(Any& array, sal_Int32 index, const Any& value)
1209 throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException )
1211 mxObjIdlArray->set( array, index, value );
1215 //**************************************************
1216 //*** Implementation von ImplIntrospectionAccess ***
1217 //**************************************************
1219 // Methoden von XIntrospectionAccess
1220 sal_Int32 ImplIntrospectionAccess::getSuppliedMethodConcepts(void)
1221 throw( RuntimeException )
1223 return MethodConcept::DANGEROUS |
1224 PROPERTY |
1225 LISTENER |
1226 ENUMERATION |
1227 NAMECONTAINER |
1228 INDEXCONTAINER;
1231 sal_Int32 ImplIntrospectionAccess::getSuppliedPropertyConcepts(void)
1232 throw( RuntimeException )
1234 return PropertyConcept::DANGEROUS |
1235 PROPERTYSET |
1236 ATTRIBUTES |
1237 METHODS;
1240 Property ImplIntrospectionAccess::getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
1241 throw( NoSuchElementException, RuntimeException )
1243 Property aRet;
1244 sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
1245 sal_Bool bFound = sal_False;
1246 if( i != -1 )
1248 sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
1249 if( (PropertyConcepts & nConcept) != 0 )
1251 const Property* pProps = mpStaticImpl->getProperties().getConstArray();
1252 aRet = pProps[ i ];
1253 bFound = sal_True;
1256 if( !bFound )
1257 throw NoSuchElementException() ;
1258 return aRet;
1261 sal_Bool ImplIntrospectionAccess::hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
1262 throw( RuntimeException )
1264 sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
1265 sal_Bool bRet = sal_False;
1266 if( i != -1 )
1268 sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
1269 if( (PropertyConcepts & nConcept) != 0 )
1270 bRet = sal_True;
1272 return bRet;
1275 Sequence< Property > ImplIntrospectionAccess::getProperties(sal_Int32 PropertyConcepts)
1276 throw( RuntimeException )
1278 // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
1279 sal_Int32 nAllSupportedMask = PROPERTYSET |
1280 ATTRIBUTES |
1281 METHODS;
1282 if( ( PropertyConcepts & nAllSupportedMask ) == nAllSupportedMask )
1284 return mpStaticImpl->getProperties();
1287 // Gleiche Sequence wie beim vorigen mal?
1288 if( mnLastPropertyConcept == PropertyConcepts )
1290 return maLastPropertySeq;
1293 // Anzahl der zu liefernden Properties
1294 sal_Int32 nCount = 0;
1296 // Es gibt zur Zeit keine DANGEROUS-Properties
1297 // if( PropertyConcepts & DANGEROUS )
1298 // nCount += mpStaticImpl->mnDangerousPropCount;
1299 if( PropertyConcepts & PROPERTYSET )
1300 nCount += mpStaticImpl->mnPropertySetPropCount;
1301 if( PropertyConcepts & ATTRIBUTES )
1302 nCount += mpStaticImpl->mnAttributePropCount;
1303 if( PropertyConcepts & METHODS )
1304 nCount += mpStaticImpl->mnMethodPropCount;
1306 // Sequence entsprechend der geforderten Anzahl reallocieren
1307 ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen
1308 pThis->maLastPropertySeq.realloc( nCount );
1309 Property* pDestProps = pThis->maLastPropertySeq.getArray();
1311 // Alle Properties durchgehen und entsprechend der Concepte uebernehmen
1312 Sequence<Property> aPropSeq = mpStaticImpl->getProperties();
1313 const Property* pSourceProps = aPropSeq.getConstArray();
1314 const sal_Int32* pConcepts = mpStaticImpl->getPropertyConcepts().getConstArray();
1315 sal_Int32 nLen = aPropSeq.getLength();
1317 sal_Int32 iDest = 0;
1318 for( sal_Int32 i = 0 ; i < nLen ; i++ )
1320 sal_Int32 nConcept = pConcepts[ i ];
1321 if( nConcept & PropertyConcepts )
1322 pDestProps[ iDest++ ] = pSourceProps[ i ];
1325 // Property mit Concepts ausgeben
1326 OUString aPropName = pSourceProps[ i ].Name;
1327 String aNameStr = OOUStringToString(aPropName, CHARSET_SYSTEM);
1328 String ConceptStr;
1329 if( nConcept & PROPERTYSET )
1330 ConceptStr += "PROPERTYSET";
1331 if( nConcept & ATTRIBUTES )
1332 ConceptStr += "ATTRIBUTES";
1333 if( nConcept & METHODS )
1334 ConceptStr += "METHODS";
1335 printf( "Property %ld: %s, Concept = %s\n", i, aNameStr.GetStr(), ConceptStr.GetStr() );
1339 // PropertyConcept merken, dies entspricht maLastPropertySeq
1340 pThis->mnLastPropertyConcept = PropertyConcepts;
1342 // Zusammengebastelte Sequence liefern
1343 return maLastPropertySeq;
1346 Reference<XIdlMethod> ImplIntrospectionAccess::getMethod(const OUString& Name, sal_Int32 MethodConcepts)
1347 throw( NoSuchMethodException, RuntimeException )
1349 Reference<XIdlMethod> xRet;
1350 sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
1351 if( i != -1 )
1354 sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
1355 if( (MethodConcepts & nConcept) != 0 )
1357 const Reference<XIdlMethod>* pMethods = mpStaticImpl->getMethods().getConstArray();
1358 xRet = pMethods[i];
1361 if( !xRet.is() )
1362 throw NoSuchMethodException();
1363 return xRet;
1366 sal_Bool ImplIntrospectionAccess::hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
1367 throw( RuntimeException )
1369 sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
1370 sal_Bool bRet = sal_False;
1371 if( i != -1 )
1373 sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
1374 if( (MethodConcepts & nConcept) != 0 )
1375 bRet = sal_True;
1377 return bRet;
1380 Sequence< Reference<XIdlMethod> > ImplIntrospectionAccess::getMethods(sal_Int32 MethodConcepts)
1381 throw( RuntimeException )
1383 ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen
1385 // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
1386 sal_Int32 nAllSupportedMask = MethodConcept::DANGEROUS |
1387 PROPERTY |
1388 LISTENER |
1389 ENUMERATION |
1390 NAMECONTAINER |
1391 INDEXCONTAINER |
1392 MethodConcept_NORMAL_IMPL;
1393 if( ( MethodConcepts & nAllSupportedMask ) == nAllSupportedMask )
1395 return mpStaticImpl->getMethods();
1398 // Gleiche Sequence wie beim vorigen mal?
1399 if( mnLastMethodConcept == MethodConcepts )
1401 return maLastMethodSeq;
1404 // Methoden-Sequences besorgen
1405 Sequence< Reference<XIdlMethod> > aMethodSeq = mpStaticImpl->getMethods();
1406 const Reference<XIdlMethod>* pSourceMethods = aMethodSeq.getConstArray();
1407 const sal_Int32* pConcepts = mpStaticImpl->getMethodConcepts().getConstArray();
1408 sal_Int32 nLen = aMethodSeq.getLength();
1410 // Sequence entsprechend der geforderten Anzahl reallocieren
1411 // Anders als bei den Properties kann die Anzahl nicht durch
1412 // Zaehler in inspect() vorher ermittelt werden, da Methoden
1413 // mehreren Konzepten angehoeren koennen
1414 pThis->maLastMethodSeq.realloc( nLen );
1415 Reference<XIdlMethod>* pDestMethods = pThis->maLastMethodSeq.getArray();
1417 // Alle Methods durchgehen und entsprechend der Concepte uebernehmen
1418 sal_Int32 iDest = 0;
1419 for( sal_Int32 i = 0 ; i < nLen ; i++ )
1421 sal_Int32 nConcept = pConcepts[ i ];
1422 if( nConcept & MethodConcepts )
1423 pDestMethods[ iDest++ ] = pSourceMethods[ i ];
1425 #if OSL_DEBUG_LEVEL > 0
1426 static bool debug = false;
1427 if ( debug )
1429 // Methode mit Concepts ausgeben
1430 const Reference< XIdlMethod >& rxMethod = pSourceMethods[ i ];
1431 ::rtl::OString aNameStr = ::rtl::OUStringToOString( rxMethod->getName(), osl_getThreadTextEncoding() );
1432 ::rtl::OString ConceptStr;
1433 if( nConcept & MethodConcept::DANGEROUS )
1434 ConceptStr += "DANGEROUS |";
1435 if( nConcept & MethodConcept::PROPERTY )
1436 ConceptStr += "PROPERTY |";
1437 if( nConcept & MethodConcept::LISTENER )
1438 ConceptStr += "LISTENER |";
1439 if( nConcept & MethodConcept::ENUMERATION )
1440 ConceptStr += "ENUMERATION |";
1441 if( nConcept & MethodConcept::NAMECONTAINER )
1442 ConceptStr += "NAMECONTAINER |";
1443 if( nConcept & MethodConcept::INDEXCONTAINER )
1444 ConceptStr += "INDEXCONTAINER |";
1445 OSL_TRACE( "Method %ld: %s, Concepts = %s", i, aNameStr.getStr(), ConceptStr.getStr() );
1447 #endif
1450 // Auf die richtige Laenge bringen
1451 pThis->maLastMethodSeq.realloc( iDest );
1453 // MethodConcept merken, dies entspricht maLastMethodSeq
1454 pThis->mnLastMethodConcept = MethodConcepts;
1456 // Zusammengebastelte Sequence liefern
1457 return maLastMethodSeq;
1460 Sequence< Type > ImplIntrospectionAccess::getSupportedListeners(void)
1461 throw( RuntimeException )
1463 return mpStaticImpl->getSupportedListeners();
1466 Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type& rType )
1467 throw( IllegalTypeException, RuntimeException )
1469 // Gibt es schon einen Adapter?
1470 if( !mpAdapter )
1472 ((ImplIntrospectionAccess*)this)->mpAdapter =
1473 new ImplIntrospectionAdapter( this, maInspectedObject, mpStaticImpl );
1475 // Selbst eine Referenz halten
1476 mpAdapter->acquire();
1479 Reference<XInterface> xRet;
1480 Any aIfaceAny( mpAdapter->queryInterface( rType ) );
1481 if( aIfaceAny.hasValue() )
1482 xRet = *(Reference<XInterface>*)aIfaceAny.getValue();
1484 return xRet;
1487 // Methoden von XMaterialHolder
1488 Any ImplIntrospectionAccess::getMaterial(void) throw(RuntimeException)
1490 return maInspectedObject;
1493 // Hilfs-Funktion zur LowerCase-Wandlung eines OUString
1494 OUString toLower( OUString aUStr )
1496 // Tabelle fuer XExactName pflegen
1497 ::rtl::OUString aOWStr( aUStr.getStr() );
1498 ::rtl::OUString aOWLowerStr = aOWStr.toAsciiLowerCase();
1499 OUString aLowerUStr( aOWLowerStr.getStr() );
1500 return aLowerUStr;
1503 // Methoden von XExactName
1504 OUString ImplIntrospectionAccess::getExactName( const OUString& rApproximateName ) throw( RuntimeException )
1506 OUString aRetStr;
1507 LowerToExactNameMap::iterator aIt =
1508 mpStaticImpl->maLowerToExactNameMap.find( toLower( rApproximateName ) );
1509 if( !( aIt == mpStaticImpl->maLowerToExactNameMap.end() ) )
1510 aRetStr = (*aIt).second;
1511 return aRetStr;
1515 //-----------------------------------------------------------------------------
1517 #ifdef USE_INTROSPECTION_CACHE
1519 struct hashIntrospectionKey_Impl
1521 Sequence< Reference<XIdlClass> > aIdlClasses;
1522 Reference<XPropertySetInfo> xPropInfo;
1523 Reference<XIdlClass> xImplClass;
1524 sal_Int32 nHitCount;
1526 void IncHitCount() const { ((hashIntrospectionKey_Impl*)this)->nHitCount++; }
1527 hashIntrospectionKey_Impl() : nHitCount( 0 ) {}
1528 hashIntrospectionKey_Impl( const Sequence< Reference<XIdlClass> > & rIdlClasses,
1529 const Reference<XPropertySetInfo> & rxPropInfo,
1530 const Reference<XIdlClass> & rxImplClass );
1533 hashIntrospectionKey_Impl::hashIntrospectionKey_Impl
1535 const Sequence< Reference<XIdlClass> > & rIdlClasses,
1536 const Reference<XPropertySetInfo> & rxPropInfo,
1537 const Reference<XIdlClass> & rxImplClass
1539 : aIdlClasses( rIdlClasses )
1540 , xPropInfo( rxPropInfo )
1541 , xImplClass( rxImplClass )
1542 , nHitCount( 0 )
1546 struct hashIntrospectionAccessCache_Impl
1548 size_t operator()(const hashIntrospectionKey_Impl & rObj ) const
1550 return (size_t)rObj.xImplClass.get() ^ (size_t)rObj.xPropInfo.get();
1553 bool operator()( const hashIntrospectionKey_Impl & rObj1,
1554 const hashIntrospectionKey_Impl & rObj2 ) const
1556 if( rObj1.xPropInfo != rObj2.xPropInfo
1557 || rObj1.xImplClass != rObj2.xImplClass )
1558 return sal_False;
1560 sal_Int32 nCount1 = rObj1.aIdlClasses.getLength();
1561 sal_Int32 nCount2 = rObj2.aIdlClasses.getLength();
1562 if( nCount1 != nCount2 )
1563 return sal_False;
1565 const Reference<XIdlClass>* pRefs1 = rObj1.aIdlClasses.getConstArray();
1566 const Reference<XIdlClass>* pRefs2 = rObj2.aIdlClasses.getConstArray();
1567 return memcmp( pRefs1, pRefs2, nCount1 * sizeof( Reference<XIdlClass> ) ) == 0;
1572 typedef std::hash_map
1574 hashIntrospectionKey_Impl,
1575 IntrospectionAccessStatic_Impl*,
1576 hashIntrospectionAccessCache_Impl,
1577 hashIntrospectionAccessCache_Impl
1579 IntrospectionAccessCacheMap_Impl;
1581 class IntrospectionAccessCacheMap : public IntrospectionAccessCacheMap_Impl
1583 public:
1584 ~IntrospectionAccessCacheMap()
1586 IntrospectionAccessCacheMap::iterator iter = begin();
1587 IntrospectionAccessCacheMap::iterator stop = this->end();
1588 while( iter != stop )
1591 (*iter).second->release();
1592 (*iter).second = NULL;
1593 iter++;
1599 // For XTypeProvider
1600 struct hashTypeProviderKey_Impl
1602 Reference<XPropertySetInfo> xPropInfo;
1603 Sequence< sal_Int8 > maImpIdSeq;
1604 sal_Int32 nHitCount;
1606 void IncHitCount() const { ((hashTypeProviderKey_Impl*)this)->nHitCount++; }
1607 hashTypeProviderKey_Impl() : nHitCount( 0 ) {}
1608 hashTypeProviderKey_Impl( const Reference<XPropertySetInfo> & rxPropInfo, const Sequence< sal_Int8 > & aImpIdSeq_ );
1611 hashTypeProviderKey_Impl::hashTypeProviderKey_Impl
1613 const Reference<XPropertySetInfo> & rxPropInfo,
1614 const Sequence< sal_Int8 > & aImpIdSeq_
1616 : xPropInfo( rxPropInfo )
1617 , maImpIdSeq( aImpIdSeq_ )
1618 , nHitCount( 0 )
1622 struct TypeProviderAccessCache_Impl
1624 size_t operator()(const hashTypeProviderKey_Impl & rObj ) const;
1626 bool operator()( const hashTypeProviderKey_Impl & rObj1,
1627 const hashTypeProviderKey_Impl & rObj2 ) const
1629 if( rObj1.xPropInfo != rObj2.xPropInfo )
1630 return sal_False;
1632 bool bEqual = false;
1633 sal_Int32 nLen1 = rObj1.maImpIdSeq.getLength();
1634 sal_Int32 nLen2 = rObj2.maImpIdSeq.getLength();
1635 if( nLen1 == nLen2 && nLen1 > 0 )
1637 const sal_Int8* pId1 = rObj1.maImpIdSeq.getConstArray();
1638 const sal_Int8* pId2 = rObj2.maImpIdSeq.getConstArray();
1639 bEqual = (memcmp( pId1, pId2, nLen1 * sizeof( sal_Int8 ) ) == 0 );
1641 return bEqual;
1645 size_t TypeProviderAccessCache_Impl::operator()(const hashTypeProviderKey_Impl & rObj ) const
1647 const sal_Int32* pBytesAsInt32Array = (const sal_Int32*)rObj.maImpIdSeq.getConstArray();
1648 sal_Int32 nLen = rObj.maImpIdSeq.getLength();
1649 sal_Int32 nCount32 = nLen / 4;
1650 sal_Int32 nMod32 = nLen % 4;
1652 // XOR with full 32 bit values
1653 sal_Int32 nId32 = 0;
1654 sal_Int32 i;
1655 for( i = 0 ; i < nCount32 ; i++ )
1656 nId32 ^= *(pBytesAsInt32Array++);
1658 // XOR with remaining byte values
1659 if( nMod32 )
1661 const sal_Int8* pBytes = (const sal_Int8*)pBytesAsInt32Array;
1662 sal_Int8* pInt8_Id32 = (sal_Int8*)&nId32;
1663 for( i = 0 ; i < nMod32 ; i++ )
1664 *(pInt8_Id32++) ^= *(pBytes++);
1667 return (size_t)nId32;
1671 typedef std::hash_map
1673 hashTypeProviderKey_Impl,
1674 IntrospectionAccessStatic_Impl*,
1675 TypeProviderAccessCache_Impl,
1676 TypeProviderAccessCache_Impl
1678 TypeProviderAccessCacheMap_Impl;
1680 class TypeProviderAccessCacheMap : public TypeProviderAccessCacheMap_Impl
1682 public:
1683 ~TypeProviderAccessCacheMap()
1685 TypeProviderAccessCacheMap::iterator iter = begin();
1686 TypeProviderAccessCacheMap::iterator stop = this->end();
1687 while( iter != stop )
1689 (*iter).second->release();
1690 (*iter).second = NULL;
1691 iter++;
1696 #endif
1699 //*************************
1700 //*** ImplIntrospection ***
1701 //*************************
1703 struct OIntrospectionMutex
1705 Mutex m_mutex;
1708 class ImplIntrospection : public XIntrospection
1709 , public XServiceInfo
1710 , public OIntrospectionMutex
1711 , public OComponentHelper
1713 friend class ImplMergeIntrospection;
1714 friend class ImplMVCIntrospection;
1716 // Implementation der Introspection.
1717 // ACHTUNG: RefCounting von Hand !!!
1718 IntrospectionAccessStatic_Impl* implInspect(const Any& aToInspectObj);
1720 // Save XMultiServiceFactory from createComponent
1721 Reference<XMultiServiceFactory> m_xSMgr;
1723 // CoreReflection halten
1724 Reference< XIdlReflection > mxCoreReflection;
1726 // Klassen, deren Methoden eine spezielle Rolle spielen
1727 Reference<XIdlClass> mxElementAccessClass;
1728 Reference<XIdlClass> mxNameContainerClass;
1729 Reference<XIdlClass> mxNameAccessClass;
1730 Reference<XIdlClass> mxIndexContainerClass;
1731 Reference<XIdlClass> mxIndexAccessClass;
1732 Reference<XIdlClass> mxEnumerationAccessClass;
1733 Reference<XIdlClass> mxInterfaceClass;
1734 Reference<XIdlClass> mxAggregationClass;
1735 sal_Bool mbDisposed;
1737 #ifdef USE_INTROSPECTION_CACHE
1738 sal_uInt16 mnCacheEntryCount;
1739 sal_uInt16 mnTPCacheEntryCount;
1740 IntrospectionAccessCacheMap* mpCache;
1741 TypeProviderAccessCacheMap* mpTypeProviderCache;
1742 #endif
1744 public:
1745 ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr );
1747 // Methoden von XInterface
1748 virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
1749 virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); }
1750 virtual void SAL_CALL release() throw() { OComponentHelper::release(); }
1752 // XTypeProvider
1753 Sequence< Type > SAL_CALL getTypes( ) throw( RuntimeException );
1754 Sequence<sal_Int8> SAL_CALL getImplementationId( ) throw( RuntimeException );
1756 // XServiceInfo
1757 OUString SAL_CALL getImplementationName() throw();
1758 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw();
1759 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw();
1760 static OUString SAL_CALL getImplementationName_Static( );
1761 static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(void) throw();
1763 // Methoden von XIntrospection
1764 virtual Reference<XIntrospectionAccess> SAL_CALL inspect(const Any& aToInspectObj)
1765 throw( RuntimeException );
1767 protected:
1768 // some XComponent part from OComponentHelper
1769 virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
1772 enum MethodType
1774 STANDARD_METHOD, // normale Methode, kein Bezug zu Properties oder Listenern
1775 GETSET_METHOD, // gehoert zu einer get/set-Property
1776 ADD_LISTENER_METHOD, // add-Methode einer Listener-Schnittstelle
1777 REMOVE_LISTENER_METHOD, // remove-Methode einer Listener-Schnittstelle
1778 INVALID_METHOD // Methode, deren Klasse nicht beruecksichtigt wird, z.B. XPropertySet
1781 // Ctor
1782 ImplIntrospection::ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr )
1783 : OComponentHelper( m_mutex )
1784 , m_xSMgr( rXSMgr )
1786 #ifdef USE_INTROSPECTION_CACHE
1787 mnCacheEntryCount = 0;
1788 mnTPCacheEntryCount = 0;
1789 mpCache = NULL;
1790 mpTypeProviderCache = NULL;
1791 #endif
1793 // Spezielle Klassen holen
1794 // Reference< XInterface > xServiceIface = m_xSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")) );
1795 // if( xServiceIface.is() )
1796 // mxCoreReflection = Reference< XIdlReflection >::query( xServiceIface );
1797 Reference< XPropertySet > xProps( rXSMgr, UNO_QUERY );
1798 OSL_ASSERT( xProps.is() );
1799 if (xProps.is())
1801 Reference< XComponentContext > xContext;
1802 xProps->getPropertyValue(
1803 OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
1804 OSL_ASSERT( xContext.is() );
1805 if (xContext.is())
1807 xContext->getValueByName(
1808 OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection") ) ) >>= mxCoreReflection;
1809 OSL_ENSURE( mxCoreReflection.is(), "### CoreReflection singleton not accessible!?" );
1812 if (! mxCoreReflection.is())
1814 throw DeploymentException(
1815 OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessible") ),
1816 Reference< XInterface >() );
1819 mxElementAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XElementAccess")) );
1820 mxNameContainerClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XNameContainer")) );
1821 mxNameAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XNameAccess")) );
1822 mxIndexContainerClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XIndexContainer")) );
1823 mxIndexAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XIndexAccess")) );
1824 mxEnumerationAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XEnumerationAccess")) );
1825 mxInterfaceClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface")) );
1826 mxAggregationClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XAggregation")) );
1827 mbDisposed = sal_False;
1830 // XComponent
1831 void ImplIntrospection::dispose() throw(::com::sun::star::uno::RuntimeException)
1833 OComponentHelper::dispose();
1835 #ifdef USE_INTROSPECTION_CACHE
1836 // Cache loeschen
1837 delete mpCache;
1838 mpCache = NULL;
1839 delete mpTypeProviderCache;
1840 mpTypeProviderCache = NULL;
1841 #endif
1843 mxElementAccessClass = NULL;
1844 mxNameContainerClass = NULL;
1845 mxNameAccessClass = NULL;
1846 mxIndexContainerClass = NULL;
1847 mxIndexAccessClass = NULL;
1848 mxEnumerationAccessClass = NULL;
1849 mxInterfaceClass = NULL;
1850 mxAggregationClass = NULL;
1851 mbDisposed = sal_True;
1855 //-----------------------------------------------------------------------------
1857 // XInterface
1858 Any ImplIntrospection::queryInterface( const Type & rType )
1859 throw(::com::sun::star::uno::RuntimeException)
1861 Any aRet( ::cppu::queryInterface(
1862 rType,
1863 static_cast< XIntrospection * >( this ),
1864 static_cast< XServiceInfo * >( this ) ) );
1866 return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType ));
1869 // XTypeProvider
1870 Sequence< Type > ImplIntrospection::getTypes()
1871 throw( RuntimeException )
1873 static OTypeCollection * s_pTypes = 0;
1874 if (! s_pTypes)
1876 MutexGuard aGuard( Mutex::getGlobalMutex() );
1877 if (! s_pTypes)
1879 static OTypeCollection s_aTypes(
1880 ::getCppuType( (const Reference< XIntrospection > *)0 ),
1881 ::getCppuType( (const Reference< XServiceInfo > *)0 ),
1882 OComponentHelper::getTypes() );
1883 s_pTypes = &s_aTypes;
1886 return s_pTypes->getTypes();
1889 Sequence< sal_Int8 > ImplIntrospection::getImplementationId()
1890 throw( RuntimeException )
1892 static OImplementationId * s_pId = 0;
1893 if (! s_pId)
1895 MutexGuard aGuard( Mutex::getGlobalMutex() );
1896 if (! s_pId)
1898 static OImplementationId s_aId;
1899 s_pId = &s_aId;
1902 return s_pId->getImplementationId();
1906 // XServiceInfo
1907 OUString ImplIntrospection::getImplementationName() throw()
1909 return getImplementationName_Static();
1912 // XServiceInfo
1913 sal_Bool ImplIntrospection::supportsService(const OUString& ServiceName) throw()
1915 Sequence< OUString > aSNL = getSupportedServiceNames();
1916 const OUString * pArray = aSNL.getConstArray();
1917 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1918 if( pArray[i] == ServiceName )
1919 return sal_True;
1920 return sal_False;
1923 // XServiceInfo
1924 Sequence< OUString > ImplIntrospection::getSupportedServiceNames(void) throw()
1926 return getSupportedServiceNames_Static();
1929 //*************************************************************************
1930 // Helper XServiceInfo
1931 OUString ImplIntrospection::getImplementationName_Static( )
1933 return OUString::createFromAscii( IMPLEMENTATION_NAME );
1936 // ORegistryServiceManager_Static
1937 Sequence< OUString > ImplIntrospection::getSupportedServiceNames_Static(void) throw()
1939 Sequence< OUString > aSNS( 1 );
1940 aSNS.getArray()[0] = OUString::createFromAscii( SERVICE_NAME );
1941 return aSNS;
1944 //*************************************************************************
1946 // Methoden von XIntrospection
1947 Reference<XIntrospectionAccess> ImplIntrospection::inspect(const Any& aToInspectObj)
1948 throw( RuntimeException )
1950 Reference<XIntrospectionAccess> xAccess;
1952 if ( aToInspectObj.getValueType().getTypeClass() == TypeClass_TYPE )
1954 Type aType;
1955 aToInspectObj >>= aType;
1957 Reference< XIdlClass > xIdlClass = mxCoreReflection->forName(((Type*)(aToInspectObj.getValue()))->getTypeName());
1959 if ( xIdlClass.is() )
1961 Any aRealInspectObj;
1962 aRealInspectObj <<= xIdlClass;
1964 IntrospectionAccessStatic_Impl* pStaticImpl = implInspect( aRealInspectObj );
1965 if( pStaticImpl )
1966 xAccess = new ImplIntrospectionAccess( aRealInspectObj, pStaticImpl );
1969 else
1971 IntrospectionAccessStatic_Impl* pStaticImpl = implInspect( aToInspectObj );
1972 if( pStaticImpl )
1973 xAccess = new ImplIntrospectionAccess( aToInspectObj, pStaticImpl );
1976 return xAccess;
1979 //-----------------------------------------------------------------------------
1981 // Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces
1982 struct hashInterface_Impl
1984 size_t operator()(const void* p) const
1986 return (size_t)p;
1990 struct eqInterface_Impl
1992 bool operator()(const void* p1, const void* p2) const
1994 return ( p1 == p2 );
1998 typedef std::hash_map
2000 void*,
2001 void*,
2002 hashInterface_Impl,
2003 eqInterface_Impl
2005 CheckedInterfacesMap;
2009 // TODO: Spaeter auslagern
2010 Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XMultiServiceFactory > & xMgr )
2012 static Reference< XIdlReflection > xRefl;
2014 // void als Default-Klasse eintragen
2015 Reference<XIdlClass> xRetClass;
2016 typelib_TypeDescription * pTD = 0;
2017 rType.getDescription( &pTD );
2018 if( pTD )
2020 OUString sOWName( pTD->pTypeName );
2021 if( !xRefl.is() )
2023 xRefl = Reference< XIdlReflection >( xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")) ), UNO_QUERY );
2024 OSL_ENSURE( xRefl.is(), "### no corereflection!" );
2026 xRetClass = xRefl->forName( sOWName );
2028 return xRetClass;
2031 // Implementation der Introspection.
2032 IntrospectionAccessStatic_Impl* ImplIntrospection::implInspect(const Any& aToInspectObj)
2034 MutexGuard aGuard( m_mutex );
2036 // Wenn die Introspection schon disposed ist, wird nur ein leeres Ergebnis geliefert
2037 if( mbDisposed )
2038 return NULL;
2040 // Objekt untersuchen
2041 TypeClass eType = aToInspectObj.getValueType().getTypeClass();
2042 if( eType != TypeClass_INTERFACE && eType != TypeClass_STRUCT && eType != TypeClass_EXCEPTION )
2043 return NULL;
2045 Reference<XInterface> x;
2046 if( eType == TypeClass_INTERFACE )
2048 // Interface aus dem Any besorgen
2049 x = *(Reference<XInterface>*)aToInspectObj.getValue();
2050 if( !x.is() )
2051 return NULL;
2054 #ifdef USE_INTROSPECTION_CACHE
2055 // Haben wir schon eine Cache-Instanz
2056 if( !mpCache )
2057 mpCache = new IntrospectionAccessCacheMap;
2058 if( !mpTypeProviderCache )
2059 mpTypeProviderCache = new TypeProviderAccessCacheMap;
2060 IntrospectionAccessCacheMap& aCache = *mpCache;
2061 TypeProviderAccessCacheMap& aTPCache = *mpTypeProviderCache;
2063 // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz
2064 IntrospectionAccessStatic_Impl* pAccess = NULL;
2065 #else
2066 // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz
2067 IntrospectionAccessStatic_Impl* pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
2068 #endif
2070 // Pruefen: Ist schon ein passendes Access-Objekt gecached?
2071 Sequence< Reference<XIdlClass> > SupportedClassSeq;
2072 Sequence< Type > SupportedTypesSeq;
2073 Reference<XIdlClassProvider> xClassProvider;
2074 Reference<XTypeProvider> xTypeProvider;
2075 Reference<XIdlClass> xImplClass;
2076 Reference<XPropertySetInfo> xPropSetInfo;
2077 Reference<XPropertySet> xPropSet;
2079 // Bei Interfaces XTypeProvider / XIdlClassProvider- und PropertySet-Interface anfordern
2080 if( eType == TypeClass_INTERFACE )
2082 // XIdlClassProvider
2083 xTypeProvider = Reference<XTypeProvider>::query( x );
2084 if( xTypeProvider.is() )
2086 SupportedTypesSeq = xTypeProvider->getTypes();
2087 sal_Int32 nTypeCount = SupportedTypesSeq.getLength();
2088 if( nTypeCount )
2090 SupportedClassSeq.realloc( nTypeCount );
2091 Reference<XIdlClass>* pClasses = SupportedClassSeq.getArray();
2093 const Type* pTypes = SupportedTypesSeq.getConstArray();
2094 for( sal_Int32 i = 0 ; i < nTypeCount ; i++ )
2096 pClasses[ i ] = TypeToIdlClass( pTypes[ i ], m_xSMgr );
2098 // TODO: Caching!
2101 else
2103 // XIdlClassProvider
2104 xClassProvider = Reference<XIdlClassProvider>::query( x );
2105 if( xClassProvider.is() )
2107 SupportedClassSeq = xClassProvider->getIdlClasses();
2108 if( SupportedClassSeq.getLength() )
2109 xImplClass = SupportedClassSeq.getConstArray()[0];
2112 // #70197, fuer InvocationAdapter: Interface-Typ im Any auch ohne
2113 // ClassProvider unterstuetzen
2114 if( !xClassProvider.is() && !xTypeProvider.is() )
2116 xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
2117 SupportedClassSeq.realloc( 1 );
2118 SupportedClassSeq.getArray()[ 0 ] = xImplClass;
2121 xPropSet = Reference<XPropertySet>::query( x );
2122 // Jetzt versuchen, das PropertySetInfo zu bekommen
2123 if( xPropSet.is() )
2124 xPropSetInfo = xPropSet->getPropertySetInfo();
2126 else
2128 xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
2131 #ifdef USE_INTROSPECTION_CACHE
2132 if( xTypeProvider.is() )
2134 Sequence< sal_Int8 > aImpIdSeq = xTypeProvider->getImplementationId();
2135 sal_Int32 nIdLen = aImpIdSeq.getLength();
2137 if( nIdLen )
2139 // cache only, if the descriptor class is set
2140 hashTypeProviderKey_Impl aKeySeq( xPropSetInfo, aImpIdSeq );
2142 TypeProviderAccessCacheMap::iterator aIt = aTPCache.find( aKeySeq );
2143 if( aIt == aTPCache.end() )
2145 // not found
2146 // Neue Instanz anlegen und unter dem gegebenen Key einfuegen
2147 pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
2149 // RefCount von Hand erhoehen, muss beim Entfernen
2150 // aus der Hashtable wieder released werden
2151 pAccess->acquire();
2153 // Groesse begrenzen, alten Eintrag wieder rausschmeissen
2154 if( mnTPCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE )
2156 // Access mit dem kleinsten HitCount suchen
2157 TypeProviderAccessCacheMap::iterator iter = aTPCache.begin();
2158 TypeProviderAccessCacheMap::iterator end = aTPCache.end();
2159 TypeProviderAccessCacheMap::iterator toDelete = iter;
2160 while( iter != end )
2162 if( (*iter).first.nHitCount < (*toDelete).first.nHitCount )
2163 toDelete = iter;
2164 ++iter;
2167 // Gefundenen Eintrag entfernen
2168 if( (*toDelete).second )
2169 (*toDelete).second->release();
2170 (*toDelete).second = NULL;
2171 aTPCache.erase( toDelete );
2173 else
2174 mnTPCacheEntryCount++;
2176 // Neuer Eintrage rein in die Table
2177 aKeySeq.nHitCount = 1;
2178 aTPCache[ aKeySeq ] = pAccess;
2181 else
2183 // Hit-Count erhoehen
2184 (*aIt).first.IncHitCount();
2185 return (*aIt).second;
2189 else if( xImplClass.is() )
2191 // cache only, if the descriptor class is set
2192 hashIntrospectionKey_Impl aKeySeq( SupportedClassSeq, xPropSetInfo, xImplClass );
2194 IntrospectionAccessCacheMap::iterator aIt = aCache.find( aKeySeq );
2195 if( aIt == aCache.end() )
2197 // not found
2198 // Neue Instanz anlegen und unter dem gegebenen Key einfuegen
2199 pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
2201 // RefCount von Hand erhoehen, muss beim Entfernen
2202 // aus der Hashtable wieder released werden
2203 pAccess->acquire();
2205 // Groesse begrenzen, alten Eintrag wieder rausschmeissen
2206 if( mnCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE )
2208 // Access mit dem kleinsten HitCount suchen
2209 IntrospectionAccessCacheMap::iterator iter = aCache.begin();
2210 IntrospectionAccessCacheMap::iterator end = aCache.end();
2211 IntrospectionAccessCacheMap::iterator toDelete = iter;
2212 while( iter != end )
2214 if( (*iter).first.nHitCount < (*toDelete).first.nHitCount )
2215 toDelete = iter;
2216 ++iter;
2219 // Gefundenen Eintrag entfernen
2220 if( (*toDelete).second )
2221 (*toDelete).second->release();
2222 (*toDelete).second = NULL;
2223 aCache.erase( toDelete );
2225 else
2226 mnCacheEntryCount++;
2228 // Neuer Eintrage rein in die Table
2229 aKeySeq.nHitCount = 1;
2230 aCache[ aKeySeq ] = pAccess;
2233 else
2235 // Hit-Count erhoehen
2236 (*aIt).first.IncHitCount();
2237 return (*aIt).second;
2240 #endif
2242 // Kein Access gecached -> neu anlegen
2243 Property* pAllPropArray;
2244 Reference<XInterface>* pInterfaces1;
2245 Reference<XInterface>* pInterfaces2;
2246 sal_Int16* pMapTypeArray;
2247 sal_Int32* pPropertyConceptArray;
2248 sal_Int32 i;
2250 if( !pAccess )
2251 pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
2253 // Referenzen auf wichtige Daten von pAccess
2254 sal_Int32& rPropCount = pAccess->mnPropCount;
2255 IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap;
2256 IntrospectionNameMap& rMethodNameMap = pAccess->maMethodNameMap;
2257 LowerToExactNameMap& rLowerToExactNameMap = pAccess->maLowerToExactNameMap;
2259 // Schon mal Pointer auf das eigene Property-Feld holen
2260 pAllPropArray = pAccess->maAllPropertySeq.getArray();
2261 pInterfaces1 = pAccess->aInterfaceSeq1.getArray();
2262 pInterfaces2 = pAccess->aInterfaceSeq2.getArray();
2263 pMapTypeArray = pAccess->maMapTypeSeq.getArray();
2264 pPropertyConceptArray = pAccess->maPropertyConceptSeq.getArray();
2266 //*************************
2267 //*** Analyse vornehmen ***
2268 //*************************
2269 if( eType == TypeClass_INTERFACE )
2271 // Zunaechst nach speziellen Interfaces suchen, die fuer
2272 // die Introspection von besonderer Bedeutung sind.
2274 // XPropertySet vorhanden?
2275 if( xPropSet.is() && xPropSetInfo.is() )
2277 // Gibt es auch ein FastPropertySet?
2278 Reference<XFastPropertySet> xDummy = Reference<XFastPropertySet>::query( x );
2279 sal_Bool bFast = pAccess->mbFastPropSet = xDummy.is();
2281 Sequence<Property> aPropSeq = xPropSetInfo->getProperties();
2282 const Property* pProps = aPropSeq.getConstArray();
2283 sal_Int32 nLen = aPropSeq.getLength();
2285 // Bei FastPropertySet muessen wir uns die Original-Handles merken
2286 if( bFast )
2287 pAccess->mpOrgPropertyHandleArray = new sal_Int32[ nLen ];
2289 for( i = 0 ; i < nLen ; i++ )
2291 // Property in eigene Liste uebernehmen
2292 pAccess->checkPropertyArraysSize
2293 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2294 Property& rProp = pAllPropArray[ rPropCount ];
2295 rProp = pProps[ i ];
2297 if( bFast )
2298 pAccess->mpOrgPropertyHandleArray[ i ] = rProp.Handle;
2300 // PropCount als Handle fuer das eigene FastPropertySet eintragen
2301 rProp.Handle = rPropCount;
2303 // Art der Property merken
2304 pMapTypeArray[ rPropCount ] = MAP_PROPERTY_SET;
2305 pPropertyConceptArray[ rPropCount ] = PROPERTYSET;
2306 pAccess->mnPropertySetPropCount++;
2308 // Namen in Hashtable eintragen, wenn nicht schon bekannt
2309 OUString aPropName = rProp.Name;
2311 // Haben wir den Namen schon?
2312 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2313 if( aIt == rPropNameMap.end() )
2315 // Neuer Eintrag in die Hashtable
2316 rPropNameMap[ aPropName ] = rPropCount;
2318 // Tabelle fuer XExactName pflegen
2319 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2321 else
2323 OSL_ENSURE( sal_False,
2324 OString( "Introspection: Property \"" ) +
2325 OUStringToOString( aPropName, RTL_TEXTENCODING_ASCII_US ) +
2326 OString( "\" found more than once in PropertySet" ) );
2329 // Count pflegen
2330 rPropCount++;
2335 // Jetzt alle weiteren implementierten Interfaces durchgehen
2336 // Diese muessen durch das XIdlClassProvider-Interface geliefert werden.
2337 // #70197, fuer InvocationAdapter: Interface-Typ im Any auch ohne
2338 // ClassProvider unterstuetzen
2339 //if( xClassProvider.is() )
2341 // Indizes in die Export-Tabellen
2342 sal_Int32 iAllExportedMethod = 0;
2343 sal_Int32 iAllSupportedListener = 0;
2345 // Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces
2346 CheckedInterfacesMap aCheckedInterfacesMap;
2348 // Flag, ob XInterface-Methoden erfasst werden sollen
2349 // (das darf nur einmal erfolgen, initial zulassen)
2350 sal_Bool bXInterfaceIsInvalid = sal_False;
2352 // Flag, ob die XInterface-Methoden schon erfasst wurden. Wenn sal_True,
2353 // wird bXInterfaceIsInvalid am Ende der Iface-Schleife aktiviert und
2354 // XInterface-Methoden werden danach abgeklemmt.
2355 sal_Bool bFoundXInterface = sal_False;
2357 // Schleife ueber alle vom ClassProvider angegebenen Klassen
2358 sal_Int32 nClassCount = SupportedClassSeq.getLength();
2359 for( sal_Int32 nIdx = 0 ; nIdx < nClassCount; nIdx++ )
2361 Reference<XIdlClass> xImplClass2 = SupportedClassSeq.getConstArray()[nIdx];
2362 while( xImplClass2.is() )
2364 // Interfaces der Implementation holen
2365 Sequence< Reference<XIdlClass> > aClassSeq = xImplClass2->getInterfaces();
2366 sal_Int32 nIfaceCount = aClassSeq.getLength();
2368 aClassSeq.realloc( nIfaceCount + 1 );
2369 aClassSeq.getArray()[ nIfaceCount ] = xImplClass2;
2370 nIfaceCount++;
2372 const Reference<XIdlClass>* pParamArray = aClassSeq.getConstArray();
2374 for( sal_Int32 j = 0 ; j < nIfaceCount ; j++ )
2376 const Reference<XIdlClass>& rxIfaceClass = pParamArray[j];
2378 // Pruefen, ob das Interface schon beruecksichtigt wurde.
2379 XInterface* pIface = SAL_STATIC_CAST( XInterface*, rxIfaceClass.get() );
2380 if( aCheckedInterfacesMap.count( pIface ) > 0 )
2382 // Kennen wir schon
2383 continue;
2385 else
2387 // Sonst eintragen
2388 aCheckedInterfacesMap[ pIface ] = pIface;
2391 //********************************************************************
2393 // 2. Fields als Properties registrieren
2395 // Felder holen
2396 Sequence< Reference<XIdlField> > fields = rxIfaceClass->getFields();
2397 const Reference<XIdlField>* pFields = fields.getConstArray();
2398 sal_Int32 nLen = fields.getLength();
2400 for( i = 0 ; i < nLen ; i++ )
2402 Reference<XIdlField> xField = pFields[i];
2403 Reference<XIdlClass> xPropType = xField->getType();
2405 // Ist die PropertySequence gross genug?
2406 pAccess->checkPropertyArraysSize
2407 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2409 // In eigenes Property-Array eintragen
2410 Property& rProp = pAllPropArray[ rPropCount ];
2411 OUString aFieldName = xField->getName();
2412 rProp.Name = aFieldName;
2413 rProp.Handle = rPropCount;
2414 Type aFieldType( xPropType->getTypeClass(), xPropType->getName() );
2415 rProp.Type = aFieldType;
2416 FieldAccessMode eAccessMode = xField->getAccessMode();
2417 rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
2418 eAccessMode == FieldAccessMode_CONST)
2419 ? READONLY : 0;
2421 // Namen in Hashtable eintragen
2422 OUString aPropName = rProp.Name;
2424 // Haben wir den Namen schon?
2425 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2426 if( !( aIt == rPropNameMap.end() ) )
2428 /* TODO
2429 OSL_TRACE(
2430 String( "Introspection: Property \"" ) +
2431 OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2432 String( "\" found more than once" ) );
2434 continue;
2437 // Neuer Eintrag in die Hashtable
2438 rPropNameMap[ aPropName ] = rPropCount;
2440 // Tabelle fuer XExactName pflegen
2441 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2443 // Field merken
2444 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
2445 pInterfaces1, rPropCount );
2446 pInterfaces1[ rPropCount ] = xField;
2448 // Art der Property merken
2449 pMapTypeArray[ rPropCount ] = MAP_FIELD;
2450 pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
2451 pAccess->mnAttributePropCount++;
2453 // Count pflegen
2454 rPropCount++;
2457 //********************************************************************
2459 // 3. Methoden
2461 // Zaehler fuer die gefundenen Listener
2462 sal_Int32 nListenerCount = 0;
2464 // Alle Methoden holen und merken
2465 Sequence< Reference<XIdlMethod> > methods = rxIfaceClass->getMethods();
2466 const Reference<XIdlMethod>* pSourceMethods = methods.getConstArray();
2467 sal_Int32 nSourceMethodCount = methods.getLength();
2469 // 3. a) get/set- und Listener-Methoden suchen
2471 // Feld fuer Infos ueber die Methoden anlegen, damit spaeter leicht die Methoden
2472 // gefunden werden koennen, die nicht im Zusammenhang mit Properties oder Listenern
2473 // stehen. NEU: auch MethodConceptArray initialisieren
2474 MethodType* pMethodTypes = new MethodType[ nSourceMethodCount ];
2475 sal_Int32* pLocalMethodConcepts = new sal_Int32[ nSourceMethodCount ];
2476 for( i = 0 ; i < nSourceMethodCount ; i++ )
2478 pMethodTypes[ i ] = STANDARD_METHOD;
2479 pLocalMethodConcepts[ i ] = 0;
2482 OUString aMethName;
2483 OUString aPropName;
2484 OUString aStartStr;
2485 for( i = 0 ; i < nSourceMethodCount ; i++ )
2487 // Methode ansprechen
2488 const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
2489 sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
2491 // Namen besorgen
2492 aMethName = rxMethod_i->getName();
2494 // Methoden katalogisieren
2495 // Alle (?) Methoden von XInterface filtern, damit z.B. nicht
2496 // vom Scripting aus aquire oder release gerufen werden kann
2497 if( rxMethod_i->getDeclaringClass()->equals( mxInterfaceClass ) )
2499 // XInterface-Methoden sind hiermit einmal beruecksichtigt
2500 bFoundXInterface = sal_True;
2502 if( bXInterfaceIsInvalid )
2504 pMethodTypes[ i ] = INVALID_METHOD;
2505 continue;
2507 else
2509 if( aMethName != OUString( RTL_CONSTASCII_USTRINGPARAM("queryInterface")) )
2511 rMethodConcept_i |= MethodConcept::DANGEROUS;
2512 continue;
2516 else if( rxMethod_i->getDeclaringClass()->equals( mxAggregationClass ) )
2518 if( aMethName == OUString( RTL_CONSTASCII_USTRINGPARAM("setDelegator")) )
2520 rMethodConcept_i |= MethodConcept::DANGEROUS;
2521 continue;
2524 else if( rxMethod_i->getDeclaringClass()->equals( mxElementAccessClass ) )
2526 rMethodConcept_i |= ( NAMECONTAINER |
2527 INDEXCONTAINER |
2528 ENUMERATION );
2530 else if( rxMethod_i->getDeclaringClass()->equals( mxNameContainerClass ) ||
2531 rxMethod_i->getDeclaringClass()->equals( mxNameAccessClass ) )
2533 rMethodConcept_i |= NAMECONTAINER;
2535 else if( rxMethod_i->getDeclaringClass()->equals( mxIndexContainerClass ) ||
2536 rxMethod_i->getDeclaringClass()->equals( mxIndexAccessClass ) )
2538 rMethodConcept_i |= INDEXCONTAINER;
2540 else if( rxMethod_i->getDeclaringClass()->equals( mxEnumerationAccessClass ) )
2542 rMethodConcept_i |= ENUMERATION;
2545 // Wenn der Name zu kurz ist, wird's sowieso nichts
2546 if( aMethName.getLength() <= 3 )
2547 continue;
2549 // Ist es eine get-Methode?
2550 aStartStr = aMethName.copy( 0, 3 );
2551 if( aStartStr == OUString( RTL_CONSTASCII_USTRINGPARAM("get")) )
2553 // Namen der potentiellen Property
2554 aPropName = aMethName.copy( 3 );
2556 // get-Methode darf keinen Parameter haben
2557 Sequence< Reference<XIdlClass> > getParams = rxMethod_i->getParameterTypes();
2558 if( getParams.getLength() > 0 )
2560 continue;
2563 // Haben wir den Namen schon?
2564 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2565 if( !( aIt == rPropNameMap.end() ) )
2567 /* TODO
2568 OSL_TRACE(
2569 String( "Introspection: Property \"" ) +
2570 OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2571 String( "\" found more than once" ) );
2573 continue;
2576 // Eine readonly-Property ist es jetzt mindestens schon
2577 rMethodConcept_i |= PROPERTY;
2579 pMethodTypes[i] = GETSET_METHOD;
2580 Reference<XIdlClass> xGetRetType = rxMethod_i->getReturnType();
2582 // Ist die PropertySequence gross genug?
2583 pAccess->checkPropertyArraysSize
2584 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2586 // In eigenes Property-Array eintragen
2587 Property& rProp = pAllPropArray[ rPropCount ];
2588 rProp.Name = aPropName;
2589 rProp.Handle = rPropCount;
2590 rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
2591 rProp.Attributes = READONLY;
2593 // Neuer Eintrag in die Hashtable
2594 rPropNameMap[ aPropName ] = rPropCount;
2596 // Tabelle fuer XExactName pflegen
2597 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2599 // get-Methode merken
2600 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
2601 pInterfaces1, rPropCount );
2602 pInterfaces1[ rPropCount ] = rxMethod_i;
2604 // Art der Property merken
2605 pMapTypeArray[ rPropCount ] = MAP_GETSET;
2606 pPropertyConceptArray[ rPropCount ] = METHODS;
2607 pAccess->mnMethodPropCount++;
2609 // Passende set-Methode suchen
2610 sal_Int32 k;
2611 for( k = 0 ; k < nSourceMethodCount ; k++ )
2613 // Methode ansprechen
2614 const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
2616 // Nur Methoden nehmen, die nicht schon zugeordnet sind
2617 if( k == i || pMethodTypes[k] != STANDARD_METHOD )
2618 continue;
2620 // Name holen und auswerten
2621 OUString aMethName2 = rxMethod_k->getName();
2622 OUString aStartStr2 = aMethName2.copy( 0, 3 );
2623 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2624 if( !( aStartStr2 == OUString( RTL_CONSTASCII_USTRINGPARAM("set")) ) )
2625 continue;
2627 // Ist es denn der gleiche Name?
2628 OUString aPropName2 = aMethName2.copy( 3 );
2629 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2630 if( !( aPropName == aPropName2 ) )
2631 continue;
2633 // set-Methode muss void returnen
2634 Reference<XIdlClass> xSetRetType = rxMethod_k->getReturnType();
2635 if( xSetRetType->getTypeClass() != TypeClass_VOID )
2637 continue;
2640 // set-Methode darf nur einen Parameter haben
2641 Sequence< Reference<XIdlClass> > setParams = rxMethod_k->getParameterTypes();
2642 sal_Int32 nParamCount = setParams.getLength();
2643 if( nParamCount != 1 )
2645 continue;
2648 // Jetzt muss nur noch der return-Typ dem Parameter-Typ entsprechen
2649 const Reference<XIdlClass>* pParamArray2 = setParams.getConstArray();
2650 Reference<XIdlClass> xParamType = pParamArray2[ 0 ];
2651 if( xParamType->equals( xGetRetType ) )
2653 pLocalMethodConcepts[ k ] = PROPERTY;
2655 pMethodTypes[k] = GETSET_METHOD;
2657 // ReadOnly-Flag wieder loschen
2658 rProp.Attributes &= ~READONLY;
2660 // set-Methode merken
2661 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
2662 pInterfaces2, rPropCount );
2663 pInterfaces2[ rPropCount ] = rxMethod_k;
2667 // Count pflegen
2668 rPropCount++;
2671 // Ist es eine addListener-Methode?
2672 else if( aStartStr == OUString( RTL_CONSTASCII_USTRINGPARAM("add")) )
2674 OUString aListenerStr( RTL_CONSTASCII_USTRINGPARAM("Listener" ) );
2676 // Namen der potentiellen Property
2677 sal_Int32 nStrLen = aMethName.getLength();
2678 sal_Int32 nCopyLen = nStrLen - aListenerStr.getLength();
2679 OUString aEndStr = aMethName.copy( nCopyLen > 0 ? nCopyLen : 0 );
2681 // Endet das Teil auf Listener?
2682 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2683 if( !( aEndStr == aListenerStr ) )
2684 continue;
2686 // Welcher Listener?
2687 OUString aListenerName = aMethName.copy( 3, nStrLen - aListenerStr.getLength() - 3 );
2689 // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
2690 // - Rueckgabe-Typ
2691 // - Anzahl und Art der Parameter
2694 // Passende remove-Methode suchen, sonst gilt's nicht
2695 sal_Int32 k;
2696 for( k = 0 ; k < nSourceMethodCount ; k++ )
2698 // Methode ansprechen
2699 const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
2701 // Nur Methoden nehmen, die nicht schon zugeordnet sind
2702 if( k == i || pMethodTypes[k] != STANDARD_METHOD )
2703 continue;
2705 // Name holen und auswerten
2706 OUString aMethName2 = rxMethod_k->getName();
2707 sal_Int32 nNameLen = aMethName2.getLength();
2708 sal_Int32 nCopyLen2 = (nNameLen < 6) ? nNameLen : 6;
2709 OUString aStartStr2 = aMethName2.copy( 0, nCopyLen2 );
2710 OUString aRemoveStr( RTL_CONSTASCII_USTRINGPARAM("remove" ) );
2711 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2712 if( !( aStartStr2 == aRemoveStr ) )
2713 continue;
2715 // Ist es denn der gleiche Listener?
2716 if( aMethName2.getLength() - aRemoveStr.getLength() <= aListenerStr.getLength() )
2717 continue;
2718 OUString aListenerName2 = aMethName2.copy
2719 ( 6, aMethName2.getLength() - aRemoveStr.getLength() - aListenerStr.getLength() );
2720 // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2721 if( !( aListenerName == aListenerName2 ) )
2722 continue;
2724 // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
2725 // - Rueckgabe-Typ
2726 // - Anzahl und Art der Parameter
2729 // Methoden sind als Listener-Schnittstelle erkannt
2730 rMethodConcept_i |= LISTENER;
2731 pLocalMethodConcepts[ k ] |= LISTENER;
2733 pMethodTypes[i] = ADD_LISTENER_METHOD;
2734 pMethodTypes[k] = REMOVE_LISTENER_METHOD;
2735 nListenerCount++;
2741 // Jetzt koennen noch SET-Methoden ohne zugehoerige GET-Methode existieren,
2742 // diese muessen zu Write-Only-Properties gemachte werden.
2743 for( i = 0 ; i < nSourceMethodCount ; i++ )
2745 // Methode ansprechen
2746 const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
2748 // Nur Methoden nehmen, die nicht schon zugeordnet sind
2749 if( pMethodTypes[i] != STANDARD_METHOD )
2750 continue;
2752 // Namen besorgen
2753 aMethName = rxMethod_i->getName();
2755 // Wenn der Name zu kurz ist, wird's sowieso nichts
2756 if( aMethName.getLength() <= 3 )
2757 continue;
2759 // Ist es eine set-Methode ohne zugehoerige get-Methode?
2760 aStartStr = aMethName.copy( 0, 3 );
2761 if( aStartStr == OUString( RTL_CONSTASCII_USTRINGPARAM("set")) )
2763 // Namen der potentiellen Property
2764 aPropName = aMethName.copy( 3 );
2766 // set-Methode muss void returnen
2767 Reference<XIdlClass> xSetRetType = rxMethod_i->getReturnType();
2768 if( xSetRetType->getTypeClass() != TypeClass_VOID )
2770 continue;
2773 // set-Methode darf nur einen Parameter haben
2774 Sequence< Reference<XIdlClass> > setParams = rxMethod_i->getParameterTypes();
2775 sal_Int32 nParamCount = setParams.getLength();
2776 if( nParamCount != 1 )
2778 continue;
2781 // Haben wir den Namen schon?
2782 IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2783 if( !( aIt == rPropNameMap.end() ) )
2785 /* TODO:
2786 OSL_TRACE(
2787 String( "Introspection: Property \"" ) +
2788 OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2789 String( "\" found more than once" ) );
2791 continue;
2794 // Alles klar, es ist eine Write-Only-Property
2795 pLocalMethodConcepts[ i ] = PROPERTY;
2797 pMethodTypes[i] = GETSET_METHOD;
2798 Reference<XIdlClass> xGetRetType = setParams.getConstArray()[0];
2800 // Ist die PropertySequence gross genug?
2801 pAccess->checkPropertyArraysSize
2802 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2804 // In eigenes Property-Array eintragen
2805 Property& rProp = pAllPropArray[ rPropCount ];
2806 rProp.Name = aPropName;
2807 rProp.Handle = rPropCount;
2808 rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
2809 rProp.Attributes = 0; // PROPERTY_WRITEONLY ???
2811 // Neuer Eintrag in die Hashtable
2812 rPropNameMap[ aPropName ] = rPropCount;
2814 // Tabelle fuer XExactName pflegen
2815 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2817 // set-Methode merken
2818 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
2819 pInterfaces2, rPropCount );
2820 pInterfaces2[ rPropCount ] = rxMethod_i;
2822 // Art der Property merken
2823 pMapTypeArray[ rPropCount ] = MAP_SETONLY;
2824 pPropertyConceptArray[ rPropCount ] = METHODS;
2825 pAccess->mnMethodPropCount++;
2827 // Count pflegen
2828 rPropCount++;
2833 //********************************************************************
2835 // 4. Methoden in die Gesamt-Sequence uebernehmen
2837 // Wieviele Methoden muessen in die Method-Sequence?
2838 sal_Int32 nExportedMethodCount = 0;
2839 sal_Int32 nSupportedListenerCount = 0;
2840 for( i = 0 ; i < nSourceMethodCount ; i++ )
2842 if( pMethodTypes[ i ] != INVALID_METHOD )
2844 nExportedMethodCount++;
2846 if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
2848 nSupportedListenerCount++;
2852 // Sequences im Access-Objekt entsprechend aufbohren
2853 pAccess->maAllMethodSeq.realloc( nExportedMethodCount + iAllExportedMethod );
2854 pAccess->maMethodConceptSeq.realloc( nExportedMethodCount + iAllExportedMethod );
2855 pAccess->maSupportedListenerSeq.realloc( nSupportedListenerCount + iAllSupportedListener );
2857 // Methoden reinschreiben
2858 Reference<XIdlMethod>* pDestMethods = pAccess->maAllMethodSeq.getArray();
2859 sal_Int32* pMethodConceptArray = pAccess->maMethodConceptSeq.getArray();
2860 Type* pListenerClassRefs = pAccess->maSupportedListenerSeq.getArray();
2861 for( i = 0 ; i < nSourceMethodCount ; i++ )
2863 if( pMethodTypes[ i ] != INVALID_METHOD )
2865 // Methode ansprechen
2866 const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
2868 // Namen in Hashtable eintragen, wenn nicht schon bekannt
2869 OUString aMethName2 = rxMethod->getName();
2870 IntrospectionNameMap::iterator aIt = rMethodNameMap.find( aMethName2 );
2871 if( aIt == rMethodNameMap.end() )
2873 // Eintragen
2874 rMethodNameMap[ aMethName2 ] = iAllExportedMethod;
2876 // Tabelle fuer XExactName pflegen
2877 rLowerToExactNameMap[ toLower( aMethName2 ) ] = aMethName2;
2879 else
2881 sal_Int32 iHashResult = (*aIt).second;
2883 Reference<XIdlMethod> xExistingMethod = pDestMethods[ iHashResult ];
2885 Reference< XIdlClass > xExistingMethClass =
2886 xExistingMethod->getDeclaringClass();
2887 Reference< XIdlClass > xNewMethClass = rxMethod->getDeclaringClass();
2888 if( xExistingMethClass->equals( xNewMethClass ) )
2889 continue;
2892 pDestMethods[ iAllExportedMethod ] = rxMethod;
2894 // Wenn kein Concept gesetzt wurde, ist die Methode "normal"
2895 sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
2896 if( !rMethodConcept_i )
2897 rMethodConcept_i = MethodConcept_NORMAL_IMPL;
2898 pMethodConceptArray[ iAllExportedMethod ] = rMethodConcept_i;
2899 iAllExportedMethod++;
2901 if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
2903 // Klasse des Listeners ermitteln
2904 const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
2906 // void als Default-Klasse eintragen
2907 Reference<XIdlClass> xListenerClass = TypeToIdlClass( getCppuVoidType(), m_xSMgr );
2908 // ALT: Reference<XIdlClass> xListenerClass = Void_getReflection()->getIdlClass();
2910 // 1. Moeglichkeit: Parameter nach einer Listener-Klasse durchsuchen
2911 // Nachteil: Superklassen muessen rekursiv durchsucht werden
2912 Sequence< Reference<XIdlClass> > aParams = rxMethod->getParameterTypes();
2913 const Reference<XIdlClass>* pParamArray2 = aParams.getConstArray();
2915 Reference<XIdlClass> xEventListenerClass = TypeToIdlClass( getCppuType( (Reference<XEventListener>*) NULL ), m_xSMgr );
2916 // ALT: Reference<XIdlClass> xEventListenerClass = XEventListener_getReflection()->getIdlClass();
2917 sal_Int32 nParamCount = aParams.getLength();
2918 sal_Int32 k;
2919 for( k = 0 ; k < nParamCount ; k++ )
2921 const Reference<XIdlClass>& rxClass = pParamArray2[k];
2923 // Sind wir von einem Listener abgeleitet?
2924 if( rxClass->equals( xEventListenerClass ) ||
2925 isDerivedFrom( rxClass, xEventListenerClass ) )
2927 xListenerClass = rxClass;
2928 break;
2932 // 2. Moeglichkeit: Namen der Methode auswerden
2933 // Nachteil: geht nicht bei Test-Listenern, die es nicht gibt
2934 //aMethName = rxMethod->getName();
2935 //aListenerName = aMethName.Copy( 3, aMethName.Len()-8-3 );
2936 //Reference<XIdlClass> xListenerClass = reflection->forName( aListenerName );
2937 Type aListenerType( TypeClass_INTERFACE, xListenerClass->getName() );
2938 pListenerClassRefs[ iAllSupportedListener ] = aListenerType;
2939 iAllSupportedListener++;
2943 // Wenn in diesem Durchlauf XInterface-Methoden
2944 // dabei waren, diese zukuenftig ignorieren
2945 if( bFoundXInterface )
2946 bXInterfaceIsInvalid = sal_True;
2948 delete[] pMethodTypes;
2949 delete[] pLocalMethodConcepts;
2952 // Super-Klasse(n) vorhanden? Dann dort fortsetzen
2953 Sequence< Reference<XIdlClass> > aSuperClassSeq = xImplClass2->getSuperclasses();
2955 // Zur Zeit wird nur von einer Superklasse ausgegangen
2956 if( aSuperClassSeq.getLength() >= 1 )
2958 xImplClass2 = aSuperClassSeq.getConstArray()[0];
2959 OSL_ENSURE( xImplClass2.is(), "super class null" );
2961 else
2963 xImplClass2 = NULL;
2968 // Anzahl der exportierten Methoden uebernehmen und Sequences anpassen
2969 // (kann abweichen, weil doppelte Methoden erst nach der Ermittlung
2970 // von nExportedMethodCount herausgeworfen werden)
2971 sal_Int32& rMethCount = pAccess->mnMethCount;
2972 rMethCount = iAllExportedMethod;
2973 pAccess->maAllMethodSeq.realloc( rMethCount );
2974 pAccess->maMethodConceptSeq.realloc( rMethCount );
2976 // Groesse der Property-Sequences anpassen
2977 pAccess->maAllPropertySeq.realloc( rPropCount );
2978 pAccess->maPropertyConceptSeq.realloc( rPropCount );
2979 pAccess->maMapTypeSeq.realloc( rPropCount );
2981 // Ende der Schleife ueber alle vom ClassProvider angegebenen Klassen
2984 // Bei structs Fields als Properties registrieren
2985 else //if( eType == TypeClass_STRUCT )
2987 // Ist es ein Interface oder eine struct?
2988 //Reference<XIdlClass> xClassRef = aToInspectObj.getReflection()->getIdlClass();
2989 Reference<XIdlClass> xClassRef = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
2990 if( !xClassRef.is() )
2992 OSL_ENSURE( sal_False, "Can't get XIdlClass from Reflection" );
2993 return pAccess;
2996 // Felder holen
2997 Sequence< Reference<XIdlField> > fields = xClassRef->getFields();
2998 const Reference<XIdlField>* pFields = fields.getConstArray();
2999 sal_Int32 nLen = fields.getLength();
3001 for( i = 0 ; i < nLen ; i++ )
3003 Reference<XIdlField> xField = pFields[i];
3004 Reference<XIdlClass> xPropType = xField->getType();
3005 OUString aPropName = xField->getName();
3007 // Ist die PropertySequence gross genug?
3008 pAccess->checkPropertyArraysSize
3009 ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
3011 // In eigenes Property-Array eintragen
3012 Property& rProp = pAllPropArray[ rPropCount ];
3013 rProp.Name = aPropName;
3014 rProp.Handle = rPropCount;
3015 rProp.Type = Type( xPropType->getTypeClass(), xPropType->getName() );
3016 FieldAccessMode eAccessMode = xField->getAccessMode();
3017 rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
3018 eAccessMode == FieldAccessMode_CONST)
3019 ? READONLY : 0;
3021 //FieldAccessMode eAccessMode = xField->getAccessMode();
3022 //rProp.Attributes = (eAccessMode == FieldAccessMode::READONLY || eAccessMode == CONST)
3023 //? PropertyAttribute::READONLY : 0;
3025 // Namen in Hashtable eintragen
3026 rPropNameMap[ aPropName ] = rPropCount;
3028 // Tabelle fuer XExactName pflegen
3029 rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
3031 // Field merken
3032 pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
3033 pInterfaces1, rPropCount );
3034 pInterfaces1[ rPropCount ] = xField;
3036 // Art der Property merken
3037 pMapTypeArray[ rPropCount ] = MAP_FIELD;
3038 pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
3039 pAccess->mnAttributePropCount++;
3041 // Count pflegen
3042 rPropCount++;
3046 // Property-Sequence auf die richtige Laenge bringen
3047 pAccess->maAllPropertySeq.realloc( pAccess->mnPropCount );
3049 return pAccess;
3052 //*************************************************************************
3053 Reference< XInterface > SAL_CALL ImplIntrospection_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr )
3054 throw( RuntimeException )
3056 Reference< XInterface > xService = (OWeakObject*)(OComponentHelper*)new ImplIntrospection( rSMgr );
3057 return xService;
3062 extern "C"
3064 //==================================================================================================
3065 void SAL_CALL component_getImplementationEnvironment(
3066 const sal_Char ** ppEnvTypeName, uno_Environment ** )
3068 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
3070 //==================================================================================================
3071 sal_Bool SAL_CALL component_writeInfo( void *, void * pRegistryKey )
3073 if (pRegistryKey)
3077 Reference< XRegistryKey > xNewKey(
3078 reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
3079 OUString::createFromAscii( "/" IMPLEMENTATION_NAME "/UNO/SERVICES" ) ) );
3081 const Sequence< OUString > & rSNL =
3082 stoc_inspect::ImplIntrospection::getSupportedServiceNames_Static();
3083 const OUString * pArray = rSNL.getConstArray();
3084 for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
3085 xNewKey->createKey( pArray[nPos] );
3087 return sal_True;
3089 catch (InvalidRegistryException &)
3091 OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
3094 return sal_False;
3096 //==================================================================================================
3097 void * SAL_CALL component_getFactory(
3098 const sal_Char * pImplName, void * pServiceManager, void * )
3100 void * pRet = 0;
3102 if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
3104 Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory(
3105 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
3106 OUString::createFromAscii( pImplName ),
3107 stoc_inspect::ImplIntrospection_CreateInstance,
3108 stoc_inspect::ImplIntrospection::getSupportedServiceNames_Static() ) );
3110 if (xFactory.is())
3112 xFactory->acquire();
3113 pRet = xFactory.get();
3117 return pRet;