Bug Summary

File:stoc/source/inspect/introspection.cxx
Location:line 1242, column 19
Description:Access to field 'mnPropertySetPropCount' results in a dereference of a null pointer

Annotated Source Code

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