Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <sal/config.h>
21 :
22 : #include <cassert>
23 : #include <cstddef>
24 : #include <limits>
25 : #include <map>
26 : #include <set>
27 :
28 : #include <osl/diagnose.h>
29 : #include <osl/mutex.hxx>
30 : #include <osl/thread.h>
31 : #include <sal/log.hxx>
32 : #include <cppuhelper/basemutex.hxx>
33 : #include <cppuhelper/compbase2.hxx>
34 : #include <cppuhelper/queryinterface.hxx>
35 : #include <cppuhelper/weak.hxx>
36 : #include <cppuhelper/component.hxx>
37 : #include <cppuhelper/factory.hxx>
38 : #include <cppuhelper/implbase3.hxx>
39 : #include <cppuhelper/supportsservice.hxx>
40 : #include <cppuhelper/typeprovider.hxx>
41 : #include <salhelper/simplereferenceobject.hxx>
42 :
43 : #include <com/sun/star/uno/DeploymentException.hpp>
44 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
45 : #include <com/sun/star/lang/XServiceInfo.hpp>
46 : #include <com/sun/star/lang/XEventListener.hpp>
47 : #include <com/sun/star/reflection/XIdlReflection.hpp>
48 : #include <com/sun/star/reflection/XIdlClass.hpp>
49 : #include <com/sun/star/reflection/XIdlField2.hpp>
50 : #include <com/sun/star/reflection/theCoreReflection.hpp>
51 : #include <com/sun/star/beans/UnknownPropertyException.hpp>
52 : #include <com/sun/star/beans/Property.hpp>
53 : #include <com/sun/star/beans/XPropertySet.hpp>
54 : #include <com/sun/star/beans/XFastPropertySet.hpp>
55 : #include <com/sun/star/beans/XIntrospection.hpp>
56 : #include <com/sun/star/beans/XIntrospectionAccess.hpp>
57 : #include <com/sun/star/beans/XMaterialHolder.hpp>
58 : #include <com/sun/star/beans/XExactName.hpp>
59 : #include <com/sun/star/beans/PropertyAttribute.hpp>
60 : #include <com/sun/star/beans/PropertyConcept.hpp>
61 : #include <com/sun/star/beans/MethodConcept.hpp>
62 : #include <com/sun/star/container/XNameContainer.hpp>
63 : #include <com/sun/star/container/XIndexContainer.hpp>
64 : #include <com/sun/star/container/XEnumerationAccess.hpp>
65 :
66 : #include <rtl/ref.hxx>
67 : #include <rtl/ustrbuf.hxx>
68 : #include <rtl/strbuf.hxx>
69 : #include <unordered_map>
70 :
71 : using namespace css::uno;
72 : using namespace css::lang;
73 : using namespace css::reflection;
74 : using namespace css::container;
75 : using namespace css::registry;
76 : using namespace css::beans;
77 : using namespace css::beans::PropertyAttribute;
78 : using namespace css::beans::PropertyConcept;
79 : using namespace css::beans::MethodConcept;
80 : using namespace cppu;
81 : using namespace osl;
82 :
83 : namespace
84 : {
85 :
86 : typedef WeakImplHelper3< XIntrospectionAccess, XMaterialHolder, XExactName > IntrospectionAccessHelper;
87 :
88 :
89 :
90 :
91 : // Special value for Method-Concept, to be able to mark "normal" functions
92 : #define MethodConcept_NORMAL_IMPL 0x80000000
93 :
94 :
95 : // Method to assert, if a class is derived from another class
96 3033 : bool isDerivedFrom( Reference<XIdlClass> xToTestClass, Reference<XIdlClass> xDerivedFromClass )
97 : {
98 3033 : Sequence< Reference<XIdlClass> > aClassesSeq = xToTestClass->getSuperclasses();
99 3033 : const Reference<XIdlClass>* pClassesArray = aClassesSeq.getConstArray();
100 :
101 3033 : sal_Int32 nSuperClassCount = aClassesSeq.getLength();
102 3034 : for ( sal_Int32 i = 0; i < nSuperClassCount; ++i )
103 : {
104 2384 : const Reference<XIdlClass>& rxClass = pClassesArray[i];
105 :
106 7154 : if ( xDerivedFromClass->equals( rxClass ) ||
107 2388 : isDerivedFrom( rxClass, xDerivedFromClass )
108 : )
109 2383 : return true;
110 : }
111 :
112 650 : return false;
113 : }
114 :
115 :
116 :
117 : // *** Classification of Properties (no enum, to be able to use Sequence) ***
118 : // Properties from a PropertySet-Interface
119 : #define MAP_PROPERTY_SET 0
120 : // Properties from Fields
121 : #define MAP_FIELD 1
122 : // Properties, that get described with get/set-Methods
123 : #define MAP_GETSET 2
124 : // Properties, with only a set-Method
125 : #define MAP_SETONLY 3
126 :
127 :
128 : // Increments, in which the size of Sequences get adjusted
129 : #define ARRAY_SIZE_STEP 20
130 :
131 :
132 :
133 :
134 : //*** IntrospectionAccessStatic_Impl ***
135 :
136 : // Equals to the old IntrospectionAccessImpl, forms now a static
137 : // part of the new Instance-related ImplIntrospectionAccess
138 :
139 : // Hashtable for the search of names
140 : typedef std::unordered_map
141 : <
142 : OUString,
143 : sal_Int32,
144 : OUStringHash
145 : >
146 : IntrospectionNameMap;
147 :
148 :
149 : // Hashtable to assign exact names to the Lower-Case
150 : // converted names, for the support of XExactName
151 : typedef std::unordered_map
152 : <
153 : OUString,
154 : OUString,
155 : OUStringHash
156 : >
157 : LowerToExactNameMap;
158 :
159 :
160 : class ImplIntrospectionAccess;
161 : class IntrospectionAccessStatic_Impl: public salhelper::SimpleReferenceObject
162 : {
163 : friend class Implementation;
164 : friend class ImplIntrospectionAccess;
165 :
166 : // Holding CoreReflection
167 : Reference< XIdlReflection > mxCoreReflection;
168 :
169 : // InterfaceSequences, to save additional information in a property
170 : // for example the Field at MAP_FIELD, the get/set-Methods at MAP_GETSET, et cetera
171 : Sequence< Reference<XInterface> > aInterfaceSeq1;
172 : Sequence< Reference<XInterface> > aInterfaceSeq2;
173 :
174 : // Hashtables for names
175 : IntrospectionNameMap maPropertyNameMap;
176 : IntrospectionNameMap maMethodNameMap;
177 : LowerToExactNameMap maLowerToExactNameMap;
178 :
179 : // Sequence of all Properties, also for delivering from getProperties()
180 : Sequence<Property> maAllPropertySeq;
181 :
182 : // Mapping of properties to Access-Types
183 : Sequence<sal_Int16> maMapTypeSeq;
184 :
185 : // Classification of found methods
186 : Sequence<sal_Int32> maPropertyConceptSeq;
187 :
188 : // Number of Properties
189 : sal_Int32 mnPropCount;
190 :
191 : // Number of Properties, which are assigned to particular concepts
192 : //sal_Int32 mnDangerousPropCount;
193 : sal_Int32 mnPropertySetPropCount;
194 : sal_Int32 mnAttributePropCount;
195 : sal_Int32 mnMethodPropCount;
196 :
197 : // Flag, if a FastPropertySet is supported
198 : bool mbFastPropSet;
199 :
200 : // Original-Handles of FastPropertySets
201 : sal_Int32* mpOrgPropertyHandleArray;
202 :
203 : // MethodSequence, that accepts all methods
204 : Sequence< Reference<XIdlMethod> > maAllMethodSeq;
205 :
206 : // Classification of found methods
207 : Sequence<sal_Int32> maMethodConceptSeq;
208 :
209 : // Number of methods
210 : sal_Int32 mnMethCount;
211 :
212 : // Sequence of Listener, that can be registered
213 : Sequence< Type > maSupportedListenerSeq;
214 :
215 : // Helper-methods for adjusting sizes of Sequences
216 : void checkPropertyArraysSize
217 : (
218 : Property*& rpAllPropArray,
219 : sal_Int16*& rpMapTypeArray,
220 : sal_Int32*& rpPropertyConceptArray,
221 : sal_Int32 iNextIndex
222 : );
223 : static void checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq, Reference<XInterface>*& rpInterfaceArray,
224 : sal_Int32 iNextIndex );
225 :
226 : public:
227 : IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ );
228 832 : virtual ~IntrospectionAccessStatic_Impl()
229 832 : {
230 416 : delete[] mpOrgPropertyHandleArray;
231 832 : }
232 : sal_Int32 getPropertyIndex( const OUString& aPropertyName ) const;
233 : sal_Int32 getMethodIndex( const OUString& aMethodName ) const;
234 :
235 : // Methods of XIntrospectionAccess (OLD, now only Impl)
236 : void setPropertyValue(const Any& obj, const OUString& aPropertyName, const Any& aValue) const;
237 : // void setPropertyValue(Any& obj, const OUString& aPropertyName, const Any& aValue) const;
238 : Any getPropertyValue(const Any& obj, const OUString& aPropertyName) const;
239 : void setPropertyValueByIndex(const Any& obj, sal_Int32 nIndex, const Any& aValue) const;
240 : // void setPropertyValueByIndex(Any& obj, sal_Int32 nIndex, const Any& aValue) const;
241 : Any getPropertyValueByIndex(const Any& obj, sal_Int32 nIndex) const;
242 :
243 1676 : Sequence<Property> getProperties() const { return maAllPropertySeq; }
244 2018 : Sequence< Reference<XIdlMethod> > getMethods() const { return maAllMethodSeq; }
245 9 : Sequence< Type > getSupportedListeners() const { return maSupportedListenerSeq; }
246 4434 : Sequence<sal_Int32> getPropertyConcepts() const { return maPropertyConceptSeq; }
247 3738 : Sequence<sal_Int32> getMethodConcepts() const { return maMethodConceptSeq; }
248 : };
249 :
250 :
251 : // Ctor
252 509 : IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ )
253 509 : : mxCoreReflection( xCoreReflection_ )
254 : {
255 509 : aInterfaceSeq1.realloc( ARRAY_SIZE_STEP );
256 509 : aInterfaceSeq2.realloc( ARRAY_SIZE_STEP );
257 :
258 : // Property-Data
259 509 : maAllPropertySeq.realloc( ARRAY_SIZE_STEP );
260 509 : maMapTypeSeq.realloc( ARRAY_SIZE_STEP );
261 509 : maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP );
262 :
263 509 : mbFastPropSet = false;
264 509 : mpOrgPropertyHandleArray = NULL;
265 :
266 509 : mnPropCount = 0;
267 : //mnDangerousPropCount = 0;
268 509 : mnPropertySetPropCount = 0;
269 509 : mnAttributePropCount = 0;
270 509 : mnMethodPropCount = 0;
271 :
272 : // Method-Data
273 509 : mnMethCount = 0;
274 509 : }
275 :
276 9238 : sal_Int32 IntrospectionAccessStatic_Impl::getPropertyIndex( const OUString& aPropertyName ) const
277 : {
278 9238 : sal_Int32 iHashResult = -1;
279 9238 : IntrospectionAccessStatic_Impl* pThis = const_cast<IntrospectionAccessStatic_Impl*>(this);
280 9238 : IntrospectionNameMap::iterator aIt = pThis->maPropertyNameMap.find( aPropertyName );
281 9238 : if( !( aIt == pThis->maPropertyNameMap.end() ) )
282 7506 : iHashResult = (*aIt).second;
283 9238 : return iHashResult;
284 : }
285 :
286 4244 : sal_Int32 IntrospectionAccessStatic_Impl::getMethodIndex( const OUString& aMethodName ) const
287 : {
288 4244 : sal_Int32 iHashResult = -1;
289 4244 : IntrospectionAccessStatic_Impl* pThis = const_cast<IntrospectionAccessStatic_Impl*>(this);
290 4244 : IntrospectionNameMap::iterator aIt = pThis->maMethodNameMap.find( aMethodName );
291 4244 : if( !( aIt == pThis->maMethodNameMap.end() ) )
292 : {
293 3543 : iHashResult = (*aIt).second;
294 : }
295 : // #95159 Check if full qualified name matches
296 : else
297 : {
298 701 : sal_Int32 nSearchFrom = aMethodName.getLength();
299 : while( true )
300 : {
301 : // Strategy: Search back until the first '_' is found
302 705 : sal_Int32 nFound = aMethodName.lastIndexOf( '_', nSearchFrom );
303 705 : if( nFound == -1 )
304 1402 : break;
305 :
306 4 : OUString aPureMethodName = aMethodName.copy( nFound + 1 );
307 :
308 4 : aIt = pThis->maMethodNameMap.find( aPureMethodName );
309 4 : if( !( aIt == pThis->maMethodNameMap.end() ) )
310 : {
311 : // Check if it can be a type?
312 : // Problem: Does not work if package names contain _ ?!
313 0 : OUString aStr = aMethodName.copy( 0, nFound );
314 0 : OUString aTypeName = aStr.replace( '_', '.' );
315 0 : Reference< XIdlClass > xClass = mxCoreReflection->forName( aTypeName );
316 0 : if( xClass.is() )
317 : {
318 : // If this is a valid class it could be the right method
319 :
320 : // Could be the right method, type has to be checked
321 0 : iHashResult = (*aIt).second;
322 :
323 0 : const Reference<XIdlMethod>* pMethods = maAllMethodSeq.getConstArray();
324 0 : const Reference<XIdlMethod> xMethod = pMethods[ iHashResult ];
325 :
326 0 : Reference< XIdlClass > xMethClass = xMethod->getDeclaringClass();
327 0 : if( xClass->equals( xMethClass ) )
328 : {
329 0 : break;
330 : }
331 : else
332 : {
333 0 : iHashResult = -1;
334 :
335 : // Could also be another method with the same name
336 : // Iterate over all methods
337 0 : sal_Int32 nLen = maAllMethodSeq.getLength();
338 0 : for( int i = 0 ; i < nLen ; ++i )
339 : {
340 0 : const Reference<XIdlMethod> xMethod2 = pMethods[ i ];
341 0 : if( xMethod2->getName() == aPureMethodName )
342 : {
343 0 : Reference< XIdlClass > xMethClass2 = xMethod2->getDeclaringClass();
344 :
345 0 : if( xClass->equals( xMethClass2 ) )
346 : {
347 0 : iHashResult = i;
348 0 : break;
349 0 : }
350 : }
351 0 : }
352 :
353 0 : if( iHashResult != -1 )
354 0 : break;
355 0 : }
356 0 : }
357 : }
358 :
359 4 : nSearchFrom = nFound - 1;
360 4 : if( nSearchFrom < 0 )
361 0 : break;
362 4 : }
363 : }
364 4244 : return iHashResult;
365 : }
366 :
367 754 : void IntrospectionAccessStatic_Impl::setPropertyValue( const Any& obj, const OUString& aPropertyName, const Any& aValue ) const
368 : //void IntrospectionAccessStatic_Impl::setPropertyValue( Any& obj, const OUString& aPropertyName, const Any& aValue ) const
369 : {
370 754 : sal_Int32 i = getPropertyIndex( aPropertyName );
371 754 : if( i != -1 )
372 754 : setPropertyValueByIndex( obj, (sal_Int32)i, aValue );
373 : else
374 0 : throw UnknownPropertyException();
375 750 : }
376 :
377 754 : void IntrospectionAccessStatic_Impl::setPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
378 : //void IntrospectionAccessStatic_Impl::setPropertyValueByIndex( Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
379 : {
380 : // Is the passed object something that fits?
381 754 : TypeClass eObjType = obj.getValueType().getTypeClass();
382 :
383 754 : Reference<XInterface> xInterface;
384 754 : if( eObjType == TypeClass_INTERFACE )
385 : {
386 615 : xInterface = *static_cast<Reference<XInterface> const *>(obj.getValue());
387 : }
388 139 : else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
389 : {
390 0 : throw IllegalArgumentException();
391 : }
392 :
393 : // Test flags
394 754 : const Property* pProps = maAllPropertySeq.getConstArray();
395 754 : if( (pProps[ nSequenceIndex ].Attributes & READONLY) != 0 )
396 : {
397 0 : throw UnknownPropertyException();
398 : }
399 :
400 754 : const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
401 754 : switch( pMapTypeArray[ nSequenceIndex ] )
402 : {
403 : case MAP_PROPERTY_SET:
404 : {
405 : // Get Property
406 17 : const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
407 :
408 : // Convert Interface-Parameter to the correct type
409 17 : bool bUseCopy = false;
410 17 : Any aRealValue;
411 :
412 17 : TypeClass eValType = aValue.getValueType().getTypeClass();
413 17 : if( eValType == TypeClass_INTERFACE )
414 : {
415 1 : Type aPropType = rProp.Type;
416 2 : OUString aTypeName( aPropType.getTypeName() );
417 2 : Reference< XIdlClass > xPropClass = mxCoreReflection->forName( aTypeName );
418 : //Reference<XIdlClass> xPropClass = rProp.Type;
419 1 : if( xPropClass.is() && xPropClass->getTypeClass() == TypeClass_INTERFACE )
420 : {
421 1 : Reference<XInterface> valInterface = *static_cast<Reference<XInterface> const *>(aValue.getValue());
422 1 : if( valInterface.is() )
423 : {
424 : //Any queryInterface( const Type& rType );
425 1 : aRealValue = valInterface->queryInterface( aPropType );
426 1 : if( aRealValue.hasValue() )
427 1 : bUseCopy = true;
428 1 : }
429 1 : }
430 : }
431 :
432 : // Do we have a FastPropertySet and a valid Handle?
433 : // CAUTION: At this point we exploit, that the PropertySet
434 : // gets queried at the beginning of the Introspection-Process.
435 : sal_Int32 nOrgHandle;
436 17 : if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
437 : {
438 : // Retrieve PropertySet-Interface
439 : Reference<XFastPropertySet> xFastPropSet =
440 3 : Reference<XFastPropertySet>::query( xInterface );
441 3 : if( xFastPropSet.is() )
442 : {
443 3 : xFastPropSet->setFastPropertyValue( nOrgHandle, bUseCopy ? aRealValue : aValue );
444 : }
445 : else
446 : {
447 : // throw UnknownPropertyException
448 3 : }
449 : }
450 : // else take the normal one
451 : else
452 : {
453 : // Retrieve PropertySet-Interface
454 : Reference<XPropertySet> xPropSet =
455 14 : Reference<XPropertySet>::query( xInterface );
456 14 : if( xPropSet.is() )
457 : {
458 14 : xPropSet->setPropertyValue( rProp.Name, bUseCopy ? aRealValue : aValue );
459 : }
460 : else
461 : {
462 : // throw UnknownPropertyException
463 14 : }
464 17 : }
465 : }
466 17 : break;
467 :
468 : case MAP_FIELD:
469 : {
470 677 : Reference<XIdlField> xField = static_cast<XIdlField*>(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
471 1354 : Reference<XIdlField2> xField2(xField, UNO_QUERY);
472 677 : if( xField2.is() )
473 : {
474 677 : xField2->set( (Any&)obj, aValue );
475 : // IllegalArgumentException
476 : // NullPointerException
477 : } else
478 0 : if( xField.is() )
479 : {
480 0 : xField->set( obj, aValue );
481 : // IllegalArgumentException
482 : // NullPointerException
483 : }
484 : else
485 : {
486 : // throw IllegalArgumentException();
487 677 : }
488 : }
489 677 : break;
490 :
491 : case MAP_GETSET:
492 : case MAP_SETONLY:
493 : {
494 : // Retrieve set-Methods
495 60 : Reference<XIdlMethod> xMethod = static_cast<XIdlMethod*>(aInterfaceSeq2.getConstArray()[ nSequenceIndex ].get());
496 60 : if( xMethod.is() )
497 : {
498 60 : Sequence<Any> args( 1 );
499 60 : args.getArray()[0] = aValue;
500 64 : xMethod->invoke( obj, args );
501 : }
502 : else
503 : {
504 : // throw IllegalArgumentException();
505 60 : }
506 : }
507 56 : break;
508 754 : }
509 750 : }
510 :
511 2318 : Any IntrospectionAccessStatic_Impl::getPropertyValue( const Any& obj, const OUString& aPropertyName ) const
512 : {
513 2318 : sal_Int32 i = getPropertyIndex( aPropertyName );
514 2318 : if( i != -1 )
515 4634 : return getPropertyValueByIndex( obj, i );
516 :
517 0 : throw UnknownPropertyException();
518 : }
519 :
520 2318 : Any IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex) const
521 : {
522 2318 : Any aRet;
523 :
524 : // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes?
525 2318 : TypeClass eObjType = obj.getValueType().getTypeClass();
526 :
527 4636 : Reference<XInterface> xInterface;
528 2318 : if( eObjType == TypeClass_INTERFACE )
529 : {
530 1880 : xInterface = *static_cast<Reference<XInterface> const *>(obj.getValue());
531 : }
532 438 : else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
533 : {
534 : // throw IllegalArgumentException();
535 0 : return aRet;
536 : }
537 :
538 2318 : const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
539 2318 : switch( pMapTypeArray[ nSequenceIndex ] )
540 : {
541 : case MAP_PROPERTY_SET:
542 : {
543 : // Property besorgen
544 3 : const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
545 :
546 : // Haben wir ein FastPropertySet und ein gueltiges Handle?
547 : // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet
548 : // zu Beginn des Introspection-Vorgangs abgefragt wird.
549 : sal_Int32 nOrgHandle;
550 3 : if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
551 : {
552 : // PropertySet-Interface holen
553 : Reference<XFastPropertySet> xFastPropSet =
554 3 : Reference<XFastPropertySet>::query( xInterface );
555 3 : if( xFastPropSet.is() )
556 : {
557 3 : aRet = xFastPropSet->getFastPropertyValue( nOrgHandle);
558 : }
559 : else
560 : {
561 : // throw UnknownPropertyException
562 0 : return aRet;
563 3 : }
564 : }
565 : // sonst eben das normale nehmen
566 : else
567 : {
568 : // PropertySet-Interface holen
569 : Reference<XPropertySet> xPropSet =
570 0 : Reference<XPropertySet>::query( xInterface );
571 0 : if( xPropSet.is() )
572 : {
573 0 : aRet = xPropSet->getPropertyValue( rProp.Name );
574 : }
575 : else
576 : {
577 : // throw UnknownPropertyException
578 0 : return aRet;
579 0 : }
580 : }
581 : }
582 3 : break;
583 :
584 : case MAP_FIELD:
585 : {
586 1991 : Reference<XIdlField> xField = static_cast<XIdlField*>(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
587 1991 : if( xField.is() )
588 : {
589 1991 : aRet = xField->get( obj );
590 : // IllegalArgumentException
591 : // NullPointerException
592 : }
593 : else
594 : {
595 : // throw IllegalArgumentException();
596 0 : return aRet;
597 1991 : }
598 : }
599 1991 : break;
600 :
601 : case MAP_GETSET:
602 : {
603 : // get-Methode holen
604 324 : Reference<XIdlMethod> xMethod = static_cast<XIdlMethod*>(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
605 324 : if( xMethod.is() )
606 : {
607 324 : Sequence<Any> args;
608 326 : aRet = xMethod->invoke( obj, args );
609 : }
610 : else
611 : {
612 : // throw IllegalArgumentException();
613 0 : return aRet;
614 324 : }
615 : }
616 322 : break;
617 :
618 : case MAP_SETONLY:
619 : // get-Methode gibt es nicht
620 : // throw WriteOnlyPropertyException();
621 0 : return aRet;
622 : }
623 2316 : return aRet;
624 : }
625 :
626 :
627 : // Hilfs-Methoden zur Groessen-Anpassung der Sequences
628 24764 : void IntrospectionAccessStatic_Impl::checkPropertyArraysSize
629 : (
630 : Property*& rpAllPropArray,
631 : sal_Int16*& rpMapTypeArray,
632 : sal_Int32*& rpPropertyConceptArray,
633 : sal_Int32 iNextIndex
634 : )
635 : {
636 24764 : sal_Int32 nLen = maAllPropertySeq.getLength();
637 24764 : if( iNextIndex >= nLen )
638 : {
639 957 : maAllPropertySeq.realloc( nLen + ARRAY_SIZE_STEP );
640 957 : rpAllPropArray = maAllPropertySeq.getArray();
641 :
642 957 : maMapTypeSeq.realloc( nLen + ARRAY_SIZE_STEP );
643 957 : rpMapTypeArray = maMapTypeSeq.getArray();
644 :
645 957 : maPropertyConceptSeq.realloc( nLen + ARRAY_SIZE_STEP );
646 957 : rpPropertyConceptArray = maPropertyConceptSeq.getArray();
647 : }
648 24764 : }
649 :
650 13250 : void IntrospectionAccessStatic_Impl::checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq,
651 : Reference<XInterface>*& rpInterfaceArray, sal_Int32 iNextIndex )
652 : {
653 13250 : sal_Int32 nLen = rSeq.getLength();
654 13250 : if( iNextIndex >= nLen )
655 : {
656 : // Neue Groesse mit ARRAY_SIZE_STEP abgleichen
657 1272 : sal_Int32 nMissingSize = iNextIndex - nLen + 1;
658 1272 : sal_Int32 nSteps = nMissingSize / ARRAY_SIZE_STEP + 1;
659 1272 : sal_Int32 nNewSize = nLen + nSteps * ARRAY_SIZE_STEP;
660 :
661 1272 : rSeq.realloc( nNewSize );
662 1272 : rpInterfaceArray = rSeq.getArray();
663 : }
664 13250 : }
665 :
666 :
667 :
668 : //*** ImplIntrospectionAccess ***
669 :
670 :
671 : // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
672 : // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
673 : // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
674 : class ImplIntrospectionAccess : public IntrospectionAccessHelper
675 : {
676 : friend class Implementation;
677 :
678 : // Untersuchtes Objekt
679 : Any maInspectedObject;
680 :
681 : // Als Interface
682 : Reference<XInterface> mxIface;
683 :
684 : // Statische Daten der Introspection
685 : rtl::Reference< IntrospectionAccessStatic_Impl > mpStaticImpl;
686 :
687 : // Adapter-Implementation
688 : WeakReference< XInterface > maAdapter;
689 :
690 : // Letzte Sequence, die bei getProperties geliefert wurde (Optimierung)
691 : Sequence<Property> maLastPropertySeq;
692 : sal_Int32 mnLastPropertyConcept;
693 :
694 : // Letzte Sequence, die bei getMethods geliefert wurde (Optimierung)
695 : Sequence<Reference<XIdlMethod> > maLastMethodSeq;
696 : sal_Int32 mnLastMethodConcept;
697 :
698 : public:
699 : ImplIntrospectionAccess( const Any& obj, rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ );
700 : virtual ~ImplIntrospectionAccess();
701 :
702 : // Methoden von XIntrospectionAccess
703 : virtual sal_Int32 SAL_CALL getSuppliedMethodConcepts()
704 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
705 : virtual sal_Int32 SAL_CALL getSuppliedPropertyConcepts()
706 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
707 : virtual Property SAL_CALL getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
708 : throw( NoSuchElementException, RuntimeException, std::exception ) SAL_OVERRIDE;
709 : virtual sal_Bool SAL_CALL hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
710 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
711 : virtual Sequence< Property > SAL_CALL getProperties(sal_Int32 PropertyConcepts)
712 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
713 : virtual Reference<XIdlMethod> SAL_CALL getMethod(const OUString& Name, sal_Int32 MethodConcepts)
714 : throw( NoSuchMethodException, RuntimeException, std::exception ) SAL_OVERRIDE;
715 : virtual sal_Bool SAL_CALL hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
716 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
717 : virtual Sequence< Reference<XIdlMethod> > SAL_CALL getMethods(sal_Int32 MethodConcepts)
718 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
719 : virtual Sequence< Type > SAL_CALL getSupportedListeners()
720 : throw( RuntimeException, std::exception ) SAL_OVERRIDE;
721 : using OWeakObject::queryAdapter;
722 : virtual Reference<XInterface> SAL_CALL queryAdapter( const Type& rType )
723 : throw( IllegalTypeException, RuntimeException, std::exception ) SAL_OVERRIDE;
724 :
725 : // Methoden von XMaterialHolder
726 : virtual Any SAL_CALL getMaterial() throw(RuntimeException, std::exception) SAL_OVERRIDE;
727 :
728 : // Methoden von XExactName
729 : virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
730 : };
731 :
732 10240 : ImplIntrospectionAccess::ImplIntrospectionAccess
733 : ( const Any& obj, rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ )
734 10240 : : maInspectedObject( obj ), mpStaticImpl( pStaticImpl_ ), maAdapter()
735 : {
736 : // Objekt als Interface merken, wenn moeglich
737 10240 : TypeClass eType = maInspectedObject.getValueType().getTypeClass();
738 10240 : if( eType == TypeClass_INTERFACE )
739 9476 : mxIface = *static_cast<Reference<XInterface> const *>(maInspectedObject.getValue());
740 :
741 10240 : mnLastPropertyConcept = -1;
742 10240 : mnLastMethodConcept = -1;
743 10240 : }
744 :
745 20310 : ImplIntrospectionAccess::~ImplIntrospectionAccess()
746 : {
747 20310 : }
748 :
749 :
750 :
751 : //*** ImplIntrospectionAdapter ***
752 :
753 :
754 : // Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
755 : // Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
756 : // ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
757 14542 : class ImplIntrospectionAdapter :
758 : public XPropertySet, public XFastPropertySet, public XPropertySetInfo,
759 : public XNameContainer, public XIndexContainer,
760 : public XEnumerationAccess, public XIdlArray,
761 : public OWeakObject
762 : {
763 : // Parent-Objekt
764 : ::rtl::Reference< ImplIntrospectionAccess > mpAccess;
765 :
766 : // Untersuchtes Objekt
767 : const Any& mrInspectedObject;
768 :
769 : // Statische Daten der Introspection
770 : rtl::Reference< IntrospectionAccessStatic_Impl > mpStaticImpl;
771 :
772 : // Objekt als Interface
773 : Reference<XInterface> mxIface;
774 :
775 : // Original-Interfaces des Objekts
776 : Reference<XElementAccess> mxObjElementAccess;
777 : Reference<XNameContainer> mxObjNameContainer;
778 : Reference<XNameAccess> mxObjNameAccess;
779 : Reference<XIndexAccess> mxObjIndexAccess;
780 : Reference<XIndexContainer> mxObjIndexContainer;
781 : Reference<XEnumerationAccess> mxObjEnumerationAccess;
782 : Reference<XIdlArray> mxObjIdlArray;
783 :
784 : public:
785 : ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
786 : const Any& obj,
787 : rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ );
788 :
789 : // Methoden von XInterface
790 : virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
791 48457 : virtual void SAL_CALL acquire() throw() SAL_OVERRIDE { OWeakObject::acquire(); }
792 48389 : virtual void SAL_CALL release() throw() SAL_OVERRIDE { OWeakObject::release(); }
793 :
794 : // Methoden von XPropertySet
795 : virtual Reference<XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( RuntimeException, std::exception ) SAL_OVERRIDE;
796 : virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName, const Any& aValue)
797 : throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
798 : virtual Any SAL_CALL getPropertyValue(const OUString& aPropertyName)
799 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
800 : virtual void SAL_CALL addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
801 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
802 : virtual void SAL_CALL removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
803 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
804 : virtual void SAL_CALL addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
805 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
806 : virtual void SAL_CALL removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
807 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
808 :
809 : // Methoden von XFastPropertySet
810 : virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const Any& aValue)
811 : throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
812 : virtual Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle)
813 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
814 :
815 : // Methoden von XPropertySetInfo
816 : virtual Sequence< Property > SAL_CALL getProperties() throw( RuntimeException, std::exception ) SAL_OVERRIDE;
817 : virtual Property SAL_CALL getPropertyByName(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
818 : virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
819 :
820 : // Methoden von XElementAccess
821 : virtual Type SAL_CALL getElementType() throw( RuntimeException, std::exception ) SAL_OVERRIDE;
822 : virtual sal_Bool SAL_CALL hasElements() throw( RuntimeException, std::exception ) SAL_OVERRIDE;
823 :
824 : // Methoden von XNameAccess
825 : virtual Any SAL_CALL getByName(const OUString& Name)
826 : throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
827 : virtual Sequence< OUString > SAL_CALL getElementNames() throw( RuntimeException, std::exception ) SAL_OVERRIDE;
828 : virtual sal_Bool SAL_CALL hasByName(const OUString& Name) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
829 :
830 : // Methoden von XNameContainer
831 : virtual void SAL_CALL insertByName(const OUString& Name, const Any& Element)
832 : throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
833 : virtual void SAL_CALL replaceByName(const OUString& Name, const Any& Element)
834 : throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
835 : virtual void SAL_CALL removeByName(const OUString& Name)
836 : throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
837 :
838 : // Methoden von XIndexAccess
839 : virtual sal_Int32 SAL_CALL getCount() throw( RuntimeException, std::exception ) SAL_OVERRIDE;
840 : virtual Any SAL_CALL getByIndex(sal_Int32 Index)
841 : throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
842 :
843 : // Methoden von XIndexContainer
844 : virtual void SAL_CALL insertByIndex(sal_Int32 Index, const Any& Element)
845 : throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
846 : virtual void SAL_CALL replaceByIndex(sal_Int32 Index, const Any& Element)
847 : throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
848 : virtual void SAL_CALL removeByIndex(sal_Int32 Index)
849 : throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception ) SAL_OVERRIDE;
850 :
851 : // Methoden von XEnumerationAccess
852 : virtual Reference<XEnumeration> SAL_CALL createEnumeration() throw( RuntimeException, std::exception ) SAL_OVERRIDE;
853 :
854 : // Methoden von XIdlArray
855 : virtual void SAL_CALL realloc(Any& array, sal_Int32 length)
856 : throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
857 : virtual sal_Int32 SAL_CALL getLen(const Any& array) throw( IllegalArgumentException, RuntimeException, std::exception ) SAL_OVERRIDE;
858 : virtual Any SAL_CALL get(const Any& array, sal_Int32 index)
859 : throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception ) SAL_OVERRIDE;
860 : virtual void SAL_CALL set(Any& array, sal_Int32 index, const Any& value)
861 : throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception ) SAL_OVERRIDE;
862 : };
863 :
864 7294 : ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
865 : const Any& obj,
866 : rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ )
867 7294 : : mpAccess( pAccess_), mrInspectedObject( obj ), mpStaticImpl( pStaticImpl_ )
868 : {
869 : // Objekt als Interfaceholen
870 7294 : TypeClass eType = mrInspectedObject.getValueType().getTypeClass();
871 7294 : if( eType == TypeClass_INTERFACE )
872 : {
873 3094 : mxIface = *static_cast<Reference< XInterface > const *>(mrInspectedObject.getValue());
874 :
875 3094 : mxObjElementAccess = Reference<XElementAccess>::query( mxIface );
876 3094 : mxObjNameAccess = Reference<XNameAccess>::query( mxIface );
877 3094 : mxObjNameContainer = Reference<XNameContainer>::query( mxIface );
878 3094 : mxObjIndexAccess = Reference<XIndexAccess>::query( mxIface );
879 3094 : mxObjIndexContainer = Reference<XIndexContainer>::query( mxIface );
880 3094 : mxObjEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface );
881 3094 : mxObjIdlArray = Reference<XIdlArray>::query( mxIface );
882 : }
883 7294 : }
884 :
885 : // Methoden von XInterface
886 23506 : Any SAL_CALL ImplIntrospectionAdapter::queryInterface( const Type& rType )
887 : throw( RuntimeException, std::exception )
888 : {
889 : Any aRet( ::cppu::queryInterface(
890 : rType,
891 : static_cast< XPropertySet * >( this ),
892 : static_cast< XFastPropertySet * >( this ),
893 23506 : static_cast< XPropertySetInfo * >( this ) ) );
894 23506 : if( !aRet.hasValue() )
895 16991 : aRet = OWeakObject::queryInterface( rType );
896 :
897 23506 : if( !aRet.hasValue() )
898 : {
899 : // Wrapper fuer die Objekt-Interfaces
900 18022 : if( ( mxObjElementAccess.is() && (aRet = ::cppu::queryInterface
901 1127 : ( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() )
902 10246 : || ( mxObjNameAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() )
903 10182 : || ( mxObjNameContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() )
904 10122 : || ( mxObjIndexAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() )
905 10116 : || ( mxObjIndexContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() )
906 10116 : || ( mxObjEnumerationAccess .is() && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() )
907 20430 : || ( mxObjIdlArray.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() )
908 : )
909 : {
910 : }
911 : }
912 23506 : return aRet;
913 : }
914 :
915 :
916 :
917 : //*** Implementation von ImplIntrospectionAdapter ***
918 :
919 :
920 : // Methoden von XPropertySet
921 4 : Reference<XPropertySetInfo> ImplIntrospectionAdapter::getPropertySetInfo()
922 : throw( RuntimeException, std::exception )
923 : {
924 4 : return static_cast<XPropertySetInfo *>(this);
925 : }
926 :
927 754 : void ImplIntrospectionAdapter::setPropertyValue(const OUString& aPropertyName, const Any& aValue)
928 : throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception )
929 : {
930 754 : mpStaticImpl->setPropertyValue( mrInspectedObject, aPropertyName, aValue );
931 750 : }
932 :
933 2318 : Any ImplIntrospectionAdapter::getPropertyValue(const OUString& aPropertyName)
934 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
935 : {
936 2318 : return mpStaticImpl->getPropertyValue( mrInspectedObject, aPropertyName );
937 : }
938 :
939 0 : void ImplIntrospectionAdapter::addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
940 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
941 : {
942 0 : if( mxIface.is() )
943 : {
944 : Reference<XPropertySet> xPropSet =
945 0 : Reference<XPropertySet>::query( mxIface );
946 : //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
947 0 : if( xPropSet.is() )
948 0 : xPropSet->addPropertyChangeListener(aPropertyName, aListener);
949 : }
950 0 : }
951 :
952 0 : void ImplIntrospectionAdapter::removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
953 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
954 : {
955 0 : if( mxIface.is() )
956 : {
957 : Reference<XPropertySet> xPropSet =
958 0 : Reference<XPropertySet>::query( mxIface );
959 : //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
960 0 : if( xPropSet.is() )
961 0 : xPropSet->removePropertyChangeListener(aPropertyName, aListener);
962 : }
963 0 : }
964 :
965 0 : void ImplIntrospectionAdapter::addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
966 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
967 : {
968 0 : if( mxIface.is() )
969 : {
970 : Reference<XPropertySet> xPropSet =
971 0 : Reference<XPropertySet>::query( mxIface );
972 : //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
973 0 : if( xPropSet.is() )
974 0 : xPropSet->addVetoableChangeListener(aPropertyName, aListener);
975 : }
976 0 : }
977 :
978 0 : void ImplIntrospectionAdapter::removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
979 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
980 : {
981 0 : if( mxIface.is() )
982 : {
983 : Reference<XPropertySet> xPropSet =
984 0 : Reference<XPropertySet>::query( mxIface );
985 0 : if( xPropSet.is() )
986 0 : xPropSet->removeVetoableChangeListener(aPropertyName, aListener);
987 : }
988 0 : }
989 :
990 :
991 : // Methoden von XFastPropertySet
992 0 : void ImplIntrospectionAdapter::setFastPropertyValue(sal_Int32, const Any&)
993 : throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception )
994 : {
995 0 : }
996 :
997 0 : Any ImplIntrospectionAdapter::getFastPropertyValue(sal_Int32)
998 : throw( UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception )
999 : {
1000 0 : return Any();
1001 : }
1002 :
1003 : // Methoden von XPropertySetInfo
1004 4 : Sequence< Property > ImplIntrospectionAdapter::getProperties() throw( RuntimeException, std::exception )
1005 : {
1006 4 : return mpStaticImpl->getProperties();
1007 : }
1008 :
1009 0 : Property ImplIntrospectionAdapter::getPropertyByName(const OUString& Name)
1010 : throw( RuntimeException, std::exception )
1011 : {
1012 0 : return mpAccess->getProperty( Name, PropertyConcept::ALL );
1013 : }
1014 :
1015 0 : sal_Bool ImplIntrospectionAdapter::hasPropertyByName(const OUString& Name)
1016 : throw( RuntimeException, std::exception )
1017 : {
1018 0 : return mpAccess->hasProperty( Name, PropertyConcept::ALL );
1019 : }
1020 :
1021 : // Methoden von XElementAccess
1022 0 : Type ImplIntrospectionAdapter::getElementType() throw( RuntimeException, std::exception )
1023 : {
1024 0 : return mxObjElementAccess->getElementType();
1025 : }
1026 :
1027 0 : sal_Bool ImplIntrospectionAdapter::hasElements() throw( RuntimeException, std::exception )
1028 : {
1029 0 : return mxObjElementAccess->hasElements();
1030 : }
1031 :
1032 : // Methoden von XNameAccess
1033 0 : Any ImplIntrospectionAdapter::getByName(const OUString& Name)
1034 : throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
1035 : {
1036 0 : return mxObjNameAccess->getByName( Name );
1037 : }
1038 :
1039 0 : Sequence< OUString > ImplIntrospectionAdapter::getElementNames()
1040 : throw( RuntimeException, std::exception )
1041 : {
1042 0 : return mxObjNameAccess->getElementNames();
1043 : }
1044 :
1045 1 : sal_Bool ImplIntrospectionAdapter::hasByName(const OUString& Name)
1046 : throw( RuntimeException, std::exception )
1047 : {
1048 1 : return mxObjNameAccess->hasByName( Name );
1049 : }
1050 :
1051 : // Methoden von XNameContainer
1052 0 : void ImplIntrospectionAdapter::insertByName(const OUString& Name, const Any& Element)
1053 : throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception )
1054 : {
1055 0 : mxObjNameContainer->insertByName( Name, Element );
1056 0 : }
1057 :
1058 0 : void ImplIntrospectionAdapter::replaceByName(const OUString& Name, const Any& Element)
1059 : throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
1060 : {
1061 0 : mxObjNameContainer->replaceByName( Name, Element );
1062 0 : }
1063 :
1064 0 : void ImplIntrospectionAdapter::removeByName(const OUString& Name)
1065 : throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
1066 : {
1067 0 : mxObjNameContainer->removeByName( Name );
1068 0 : }
1069 :
1070 : // Methoden von XIndexAccess
1071 : // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType() const
1072 0 : sal_Int32 ImplIntrospectionAdapter::getCount() throw( RuntimeException, std::exception )
1073 : {
1074 0 : return mxObjIndexAccess->getCount();
1075 : }
1076 :
1077 0 : Any ImplIntrospectionAdapter::getByIndex(sal_Int32 Index)
1078 : throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1079 : {
1080 0 : return mxObjIndexAccess->getByIndex( Index );
1081 : }
1082 :
1083 : // Methoden von XIndexContainer
1084 0 : void ImplIntrospectionAdapter::insertByIndex(sal_Int32 Index, const Any& Element)
1085 : throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1086 : {
1087 0 : mxObjIndexContainer->insertByIndex( Index, Element );
1088 0 : }
1089 :
1090 0 : void ImplIntrospectionAdapter::replaceByIndex(sal_Int32 Index, const Any& Element)
1091 : throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1092 : {
1093 0 : mxObjIndexContainer->replaceByIndex( Index, Element );
1094 0 : }
1095 :
1096 0 : void ImplIntrospectionAdapter::removeByIndex(sal_Int32 Index)
1097 : throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1098 : {
1099 0 : mxObjIndexContainer->removeByIndex( Index );
1100 0 : }
1101 :
1102 : // Methoden von XEnumerationAccess
1103 : // Schon in XNameAccess: virtual Reference<XIdlClass> getElementType() const;
1104 0 : Reference<XEnumeration> ImplIntrospectionAdapter::createEnumeration() throw( RuntimeException, std::exception )
1105 : {
1106 0 : return mxObjEnumerationAccess->createEnumeration();
1107 : }
1108 :
1109 : // Methoden von XIdlArray
1110 0 : void ImplIntrospectionAdapter::realloc(Any& array, sal_Int32 length)
1111 : throw( IllegalArgumentException, RuntimeException, std::exception )
1112 : {
1113 0 : mxObjIdlArray->realloc( array, length );
1114 0 : }
1115 :
1116 0 : sal_Int32 ImplIntrospectionAdapter::getLen(const Any& array)
1117 : throw( IllegalArgumentException, RuntimeException, std::exception )
1118 : {
1119 0 : return mxObjIdlArray->getLen( array );
1120 : }
1121 :
1122 0 : Any ImplIntrospectionAdapter::get(const Any& array, sal_Int32 index)
1123 : throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception )
1124 : {
1125 0 : return mxObjIdlArray->get( array, index );
1126 : }
1127 :
1128 0 : void ImplIntrospectionAdapter::set(Any& array, sal_Int32 index, const Any& value)
1129 : throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception )
1130 : {
1131 0 : mxObjIdlArray->set( array, index, value );
1132 0 : }
1133 :
1134 :
1135 :
1136 : //*** Implementation von ImplIntrospectionAccess ***
1137 :
1138 :
1139 : // Methoden von XIntrospectionAccess
1140 0 : sal_Int32 ImplIntrospectionAccess::getSuppliedMethodConcepts()
1141 : throw( RuntimeException, std::exception )
1142 : {
1143 : return MethodConcept::DANGEROUS |
1144 : PROPERTY |
1145 : LISTENER |
1146 : ENUMERATION |
1147 : NAMECONTAINER |
1148 0 : INDEXCONTAINER;
1149 : }
1150 :
1151 0 : sal_Int32 ImplIntrospectionAccess::getSuppliedPropertyConcepts()
1152 : throw( RuntimeException, std::exception )
1153 : {
1154 : return PropertyConcept::DANGEROUS |
1155 : PROPERTYSET |
1156 : ATTRIBUTES |
1157 0 : METHODS;
1158 : }
1159 :
1160 1672 : Property ImplIntrospectionAccess::getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
1161 : throw( NoSuchElementException, RuntimeException, std::exception )
1162 : {
1163 1672 : Property aRet;
1164 1672 : sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
1165 1672 : bool bFound = false;
1166 1672 : if( i != -1 )
1167 : {
1168 1672 : sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
1169 1672 : if( (PropertyConcepts & nConcept) != 0 )
1170 : {
1171 1672 : const Property* pProps = mpStaticImpl->getProperties().getConstArray();
1172 1672 : aRet = pProps[ i ];
1173 1672 : bFound = true;
1174 : }
1175 : }
1176 1672 : if( !bFound )
1177 0 : throw NoSuchElementException() ;
1178 1672 : return aRet;
1179 : }
1180 :
1181 4494 : sal_Bool ImplIntrospectionAccess::hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
1182 : throw( RuntimeException, std::exception )
1183 : {
1184 4494 : sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
1185 4494 : bool bRet = false;
1186 4494 : if( i != -1 )
1187 : {
1188 2762 : sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
1189 2762 : if( (PropertyConcepts & nConcept) != 0 )
1190 2762 : bRet = true;
1191 : }
1192 4494 : return bRet;
1193 : }
1194 :
1195 0 : Sequence< Property > ImplIntrospectionAccess::getProperties(sal_Int32 PropertyConcepts)
1196 : throw( RuntimeException, std::exception )
1197 : {
1198 : // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
1199 : sal_Int32 nAllSupportedMask = PROPERTYSET |
1200 : ATTRIBUTES |
1201 0 : METHODS;
1202 0 : if( ( PropertyConcepts & nAllSupportedMask ) == nAllSupportedMask )
1203 : {
1204 0 : return mpStaticImpl->getProperties();
1205 : }
1206 :
1207 : // Gleiche Sequence wie beim vorigen mal?
1208 0 : if( mnLastPropertyConcept == PropertyConcepts )
1209 : {
1210 0 : return maLastPropertySeq;
1211 : }
1212 :
1213 : // Anzahl der zu liefernden Properties
1214 0 : sal_Int32 nCount = 0;
1215 :
1216 : // Es gibt zur Zeit keine DANGEROUS-Properties
1217 : // if( PropertyConcepts & DANGEROUS )
1218 : // nCount += mpStaticImpl->mnDangerousPropCount;
1219 0 : if( PropertyConcepts & PROPERTYSET )
1220 0 : nCount += mpStaticImpl->mnPropertySetPropCount;
1221 0 : if( PropertyConcepts & ATTRIBUTES )
1222 0 : nCount += mpStaticImpl->mnAttributePropCount;
1223 0 : if( PropertyConcepts & METHODS )
1224 0 : nCount += mpStaticImpl->mnMethodPropCount;
1225 :
1226 : // Sequence entsprechend der geforderten Anzahl reallocieren
1227 0 : maLastPropertySeq.realloc( nCount );
1228 0 : Property* pDestProps = maLastPropertySeq.getArray();
1229 :
1230 : // Alle Properties durchgehen und entsprechend der Concepte uebernehmen
1231 0 : Sequence<Property> aPropSeq = mpStaticImpl->getProperties();
1232 0 : const Property* pSourceProps = aPropSeq.getConstArray();
1233 0 : const sal_Int32* pConcepts = mpStaticImpl->getPropertyConcepts().getConstArray();
1234 0 : sal_Int32 nLen = aPropSeq.getLength();
1235 :
1236 0 : sal_Int32 iDest = 0;
1237 0 : for( sal_Int32 i = 0 ; i < nLen ; i++ )
1238 : {
1239 0 : sal_Int32 nConcept = pConcepts[ i ];
1240 0 : if( nConcept & PropertyConcepts )
1241 0 : pDestProps[ iDest++ ] = pSourceProps[ i ];
1242 : }
1243 :
1244 : // PropertyConcept merken, dies entspricht maLastPropertySeq
1245 0 : mnLastPropertyConcept = PropertyConcepts;
1246 :
1247 : // Zusammengebastelte Sequence liefern
1248 0 : return maLastPropertySeq;
1249 : }
1250 :
1251 1774 : Reference<XIdlMethod> ImplIntrospectionAccess::getMethod(const OUString& Name, sal_Int32 MethodConcepts)
1252 : throw( NoSuchMethodException, RuntimeException, std::exception )
1253 : {
1254 1774 : Reference<XIdlMethod> xRet;
1255 1774 : sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
1256 1774 : if( i != -1 )
1257 : {
1258 :
1259 1774 : sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
1260 1774 : if( (MethodConcepts & nConcept) != 0 )
1261 : {
1262 1774 : const Reference<XIdlMethod>* pMethods = mpStaticImpl->getMethods().getConstArray();
1263 1774 : xRet = pMethods[i];
1264 : }
1265 : }
1266 1774 : if( !xRet.is() )
1267 0 : throw NoSuchMethodException();
1268 1774 : return xRet;
1269 : }
1270 :
1271 2470 : sal_Bool ImplIntrospectionAccess::hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
1272 : throw( RuntimeException, std::exception )
1273 : {
1274 2470 : sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
1275 2470 : bool bRet = false;
1276 2470 : if( i != -1 )
1277 : {
1278 1769 : sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
1279 1769 : if( (MethodConcepts & nConcept) != 0 )
1280 1769 : bRet = true;
1281 : }
1282 2470 : return bRet;
1283 : }
1284 :
1285 264 : Sequence< Reference<XIdlMethod> > ImplIntrospectionAccess::getMethods(sal_Int32 MethodConcepts)
1286 : throw( RuntimeException, std::exception )
1287 : {
1288 : // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
1289 : sal_Int32 nAllSupportedMask = MethodConcept::DANGEROUS |
1290 : PROPERTY |
1291 : LISTENER |
1292 : ENUMERATION |
1293 : NAMECONTAINER |
1294 : INDEXCONTAINER |
1295 264 : MethodConcept_NORMAL_IMPL;
1296 264 : if( ( MethodConcepts & nAllSupportedMask ) == nAllSupportedMask )
1297 : {
1298 49 : return mpStaticImpl->getMethods();
1299 : }
1300 :
1301 : // Gleiche Sequence wie beim vorigen mal?
1302 215 : if( mnLastMethodConcept == MethodConcepts )
1303 : {
1304 20 : return maLastMethodSeq;
1305 : }
1306 :
1307 : // Methoden-Sequences besorgen
1308 195 : Sequence< Reference<XIdlMethod> > aMethodSeq = mpStaticImpl->getMethods();
1309 195 : const Reference<XIdlMethod>* pSourceMethods = aMethodSeq.getConstArray();
1310 195 : const sal_Int32* pConcepts = mpStaticImpl->getMethodConcepts().getConstArray();
1311 195 : sal_Int32 nLen = aMethodSeq.getLength();
1312 :
1313 : // Sequence entsprechend der geforderten Anzahl reallocieren
1314 : // Anders als bei den Properties kann die Anzahl nicht durch
1315 : // Zaehler in inspect() vorher ermittelt werden, da Methoden
1316 : // mehreren Konzepten angehoeren koennen
1317 195 : maLastMethodSeq.realloc( nLen );
1318 195 : Reference<XIdlMethod>* pDestMethods = maLastMethodSeq.getArray();
1319 :
1320 : // Alle Methods durchgehen und entsprechend der Concepte uebernehmen
1321 195 : sal_Int32 iDest = 0;
1322 15251 : for( sal_Int32 i = 0 ; i < nLen ; i++ )
1323 : {
1324 15056 : sal_Int32 nConcept = pConcepts[ i ];
1325 15056 : if( nConcept & MethodConcepts )
1326 3594 : pDestMethods[ iDest++ ] = pSourceMethods[ i ];
1327 : }
1328 :
1329 : // Auf die richtige Laenge bringen
1330 195 : maLastMethodSeq.realloc( iDest );
1331 :
1332 : // MethodConcept merken, dies entspricht maLastMethodSeq
1333 195 : mnLastMethodConcept = MethodConcepts;
1334 :
1335 : // Zusammengebastelte Sequence liefern
1336 195 : return maLastMethodSeq;
1337 : }
1338 :
1339 9 : Sequence< Type > ImplIntrospectionAccess::getSupportedListeners()
1340 : throw( RuntimeException, std::exception )
1341 : {
1342 9 : return mpStaticImpl->getSupportedListeners();
1343 : }
1344 :
1345 8092 : Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type& rType )
1346 : throw( IllegalTypeException, RuntimeException, std::exception )
1347 : {
1348 : // Gibt es schon einen Adapter?
1349 8092 : Reference< XInterface > xAdapter( maAdapter );
1350 8092 : if( !xAdapter.is() )
1351 : {
1352 7294 : xAdapter = *( new ImplIntrospectionAdapter( this, maInspectedObject, mpStaticImpl ) );
1353 7294 : maAdapter = xAdapter;
1354 : }
1355 :
1356 8092 : Reference<XInterface> xRet;
1357 8092 : xAdapter->queryInterface( rType ) >>= xRet;
1358 8092 : return xRet;
1359 : }
1360 :
1361 : // Methoden von XMaterialHolder
1362 31960 : Any ImplIntrospectionAccess::getMaterial() throw(RuntimeException, std::exception)
1363 : {
1364 31960 : return maInspectedObject;
1365 : }
1366 :
1367 : // Hilfs-Funktion zur LowerCase-Wandlung eines OUString
1368 66280 : OUString toLower( const OUString& aUStr )
1369 : {
1370 : // Tabelle fuer XExactName pflegen
1371 66280 : OUString aOWStr( aUStr.getStr() );
1372 132560 : OUString aOWLowerStr = aOWStr.toAsciiLowerCase();
1373 66280 : OUString aLowerUStr( aOWLowerStr.getStr() );
1374 132560 : return aLowerUStr;
1375 : }
1376 :
1377 : // Methoden von XExactName
1378 2970 : OUString ImplIntrospectionAccess::getExactName( const OUString& rApproximateName ) throw( RuntimeException, std::exception )
1379 : {
1380 2970 : OUString aRetStr;
1381 : LowerToExactNameMap::iterator aIt =
1382 2970 : mpStaticImpl->maLowerToExactNameMap.find( toLower( rApproximateName ) );
1383 2970 : if( !( aIt == mpStaticImpl->maLowerToExactNameMap.end() ) )
1384 2793 : aRetStr = (*aIt).second;
1385 2970 : return aRetStr;
1386 : }
1387 :
1388 905 : struct ClassKey {
1389 774 : ClassKey(
1390 : css::uno::Reference<css::beans::XPropertySetInfo> const & theProperties,
1391 : css::uno::Reference<css::reflection::XIdlClass> const &
1392 : theImplementation,
1393 : css::uno::Sequence< css::uno::Reference<css::reflection::XIdlClass> >
1394 : const & theClasses):
1395 : properties(theProperties), implementation(theImplementation),
1396 774 : classes(theClasses)
1397 774 : {}
1398 :
1399 : css::uno::Reference<css::beans::XPropertySetInfo> properties;
1400 : css::uno::Reference<css::reflection::XIdlClass> implementation;
1401 : css::uno::Sequence< css::uno::Reference<css::reflection::XIdlClass> >
1402 : classes;
1403 : };
1404 :
1405 : struct ClassKeyLess {
1406 2650 : bool operator ()(ClassKey const & key1, ClassKey const & key2) const {
1407 2650 : if (key1.properties.get() < key2.properties.get()) {
1408 0 : return true;
1409 : }
1410 2650 : if (key1.properties.get() > key2.properties.get()) {
1411 0 : return false;
1412 : }
1413 2650 : if (key1.implementation.get() < key2.implementation.get()) {
1414 932 : return true;
1415 : }
1416 1718 : if (key1.implementation.get() > key2.implementation.get()) {
1417 244 : return false;
1418 : }
1419 1474 : if (key1.classes.getLength() < key2.classes.getLength()) {
1420 0 : return true;
1421 : }
1422 1474 : if (key1.classes.getLength() > key2.classes.getLength()) {
1423 0 : return false;
1424 : }
1425 1490 : for (sal_Int32 i = 0; i != key1.classes.getLength(); ++i) {
1426 16 : if (key1.classes[i].get() < key2.classes[i].get()) {
1427 0 : return true;
1428 : }
1429 16 : if (key1.classes[i].get() > key2.classes[i].get()) {
1430 0 : return false;
1431 : }
1432 : }
1433 1474 : return false;
1434 : }
1435 : };
1436 :
1437 11307 : struct TypeKey {
1438 9466 : TypeKey(
1439 : css::uno::Reference<css::beans::XPropertySetInfo> const & theProperties,
1440 : css::uno::Sequence<css::uno::Type> const & theTypes):
1441 9466 : properties(theProperties)
1442 : {
1443 : //TODO: Could even sort the types lexicographically first, to increase
1444 : // the chance of matches between different implementations' getTypes(),
1445 : // but the old scheme of using getImplementationId() would have missed
1446 : // those matches, too:
1447 9466 : OUStringBuffer b;
1448 481434 : for (sal_Int32 i = 0; i != theTypes.getLength(); ++i) {
1449 471968 : b.append(theTypes[i].getTypeName());
1450 471968 : b.append('*'); // arbitrary delimiter not used by type grammar
1451 : }
1452 9466 : types = b.makeStringAndClear();
1453 9466 : }
1454 :
1455 : css::uno::Reference<css::beans::XPropertySetInfo> properties;
1456 : OUString types;
1457 : };
1458 :
1459 : struct TypeKeyLess {
1460 40601 : bool operator ()(TypeKey const & key1, TypeKey const & key2) const {
1461 40601 : if (key1.properties.get() < key2.properties.get()) {
1462 7321 : return true;
1463 : }
1464 33280 : if (key1.properties.get() > key2.properties.get()) {
1465 3331 : return false;
1466 : }
1467 29949 : return key1.types < key2.types;
1468 : }
1469 : };
1470 :
1471 456 : template<typename Key, typename Less> class Cache {
1472 : public:
1473 10240 : rtl::Reference<IntrospectionAccessStatic_Impl> find(Key const & key) const {
1474 10240 : typename Map::const_iterator i(map_.find(key));
1475 10240 : if (i == map_.end()) {
1476 509 : return rtl::Reference<IntrospectionAccessStatic_Impl>();
1477 : } else {
1478 9731 : if (i->second.hits < std::numeric_limits<unsigned>::max()) {
1479 9731 : ++i->second.hits;
1480 : }
1481 : assert(i->second.access.is());
1482 9731 : return i->second.access;
1483 : }
1484 : }
1485 :
1486 509 : void insert(
1487 : Key const & key,
1488 : rtl::Reference<IntrospectionAccessStatic_Impl> const & access)
1489 : {
1490 : assert(access.is());
1491 509 : typename Map::size_type const MAX = 100;
1492 : assert(map_.size() <= MAX);
1493 509 : if (map_.size() == MAX) {
1494 71 : typename Map::iterator del(map_.begin());
1495 7171 : for (typename Map::iterator i(map_.begin()); i != map_.end(); ++i) {
1496 7100 : if (i->second.hits < del->second.hits) {
1497 259 : del = i;
1498 : }
1499 : }
1500 71 : map_.erase(del);
1501 : }
1502 : bool ins = map_.insert(typename Map::value_type(key, Data(access)))
1503 509 : .second;
1504 : assert(ins); (void)ins;
1505 509 : }
1506 :
1507 232 : void clear() { map_.clear(); }
1508 :
1509 : private:
1510 2481 : struct Data {
1511 509 : explicit Data(
1512 : rtl::Reference<IntrospectionAccessStatic_Impl> const & theAccess):
1513 509 : access(theAccess), hits(1)
1514 509 : {}
1515 :
1516 : rtl::Reference<IntrospectionAccessStatic_Impl> access;
1517 : mutable unsigned hits;
1518 : };
1519 :
1520 : typedef std::map<Key, Data, Less> Map;
1521 :
1522 : Map map_;
1523 : };
1524 :
1525 : typedef
1526 : cppu::WeakComponentImplHelper2<
1527 : css::lang::XServiceInfo, css::beans::XIntrospection>
1528 : Implementation_Base;
1529 :
1530 220 : class Implementation: private cppu::BaseMutex, public Implementation_Base {
1531 : public:
1532 118 : explicit Implementation(
1533 : css::uno::Reference<css::uno::XComponentContext> const & context):
1534 : Implementation_Base(m_aMutex),
1535 118 : reflection_(css::reflection::theCoreReflection::get(context))
1536 118 : {}
1537 :
1538 : private:
1539 116 : virtual void SAL_CALL disposing() SAL_OVERRIDE {
1540 116 : reflection_.clear();
1541 116 : classCache_.clear();
1542 116 : typeCache_.clear();
1543 116 : }
1544 :
1545 1 : virtual OUString SAL_CALL getImplementationName()
1546 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
1547 1 : { return OUString("com.sun.star.comp.stoc.Introspection"); }
1548 :
1549 0 : virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
1550 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
1551 0 : { return cppu::supportsService(this, ServiceName); }
1552 :
1553 : virtual css::uno::Sequence<OUString> SAL_CALL
1554 1 : getSupportedServiceNames()
1555 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
1556 : {
1557 1 : Sequence<OUString> s(1);
1558 1 : s[0] = "com.sun.star.beans.Introspection";
1559 1 : return s;
1560 : }
1561 :
1562 : virtual css::uno::Reference<css::beans::XIntrospectionAccess> SAL_CALL
1563 : inspect(css::uno::Any const & aObject)
1564 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1565 :
1566 : css::uno::Reference<css::reflection::XIdlReflection> reflection_;
1567 : Cache<ClassKey, ClassKeyLess> classCache_;
1568 : Cache<TypeKey, TypeKeyLess> typeCache_;
1569 : };
1570 :
1571 19398 : css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
1572 : css::uno::Any const & aObject)
1573 : throw (css::uno::RuntimeException, std::exception)
1574 : {
1575 19398 : osl::MutexGuard g(m_aMutex);
1576 19398 : if (rBHelper.bDisposed || rBHelper.bInDispose) {
1577 : throw css::lang::DisposedException(
1578 0 : getImplementationName(), static_cast<OWeakObject *>(this));
1579 : }
1580 38796 : css::uno::Any aToInspectObj;
1581 38796 : css::uno::Type t;
1582 19398 : if (aObject >>= t) {
1583 : css::uno::Reference<css::reflection::XIdlClass> c(
1584 0 : reflection_->forName(t.getTypeName()));
1585 0 : if (!c.is()) {
1586 : SAL_WARN("stoc", "cannot reflect type " << t.getTypeName());
1587 0 : return css::uno::Reference<css::beans::XIntrospectionAccess>();
1588 : }
1589 0 : aToInspectObj <<= c;
1590 : } else {
1591 19398 : aToInspectObj = aObject;
1592 : }
1593 :
1594 : // Objekt untersuchen
1595 19398 : TypeClass eType = aToInspectObj.getValueType().getTypeClass();
1596 19398 : if( eType != TypeClass_INTERFACE && eType != TypeClass_STRUCT && eType != TypeClass_EXCEPTION )
1597 9158 : return css::uno::Reference<css::beans::XIntrospectionAccess>();
1598 :
1599 20480 : Reference<XInterface> x;
1600 10240 : if( eType == TypeClass_INTERFACE )
1601 : {
1602 : // Interface aus dem Any besorgen
1603 9476 : x = *static_cast<Reference<XInterface> const *>(aToInspectObj.getValue());
1604 9476 : if( !x.is() )
1605 0 : return css::uno::Reference<css::beans::XIntrospectionAccess>();
1606 : }
1607 :
1608 : // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz
1609 20480 : rtl::Reference< IntrospectionAccessStatic_Impl > pAccess;
1610 :
1611 : // Pruefen: Ist schon ein passendes Access-Objekt gecached?
1612 20480 : Sequence< Reference<XIdlClass> > SupportedClassSeq;
1613 20480 : Sequence< Type > SupportedTypesSeq;
1614 20480 : Reference<XTypeProvider> xTypeProvider;
1615 20480 : Reference<XIdlClass> xImplClass;
1616 20480 : Reference<XPropertySetInfo> xPropSetInfo;
1617 20480 : Reference<XPropertySet> xPropSet;
1618 :
1619 : // Look for interfaces XTypeProvider and PropertySet
1620 10240 : if( eType == TypeClass_INTERFACE )
1621 : {
1622 9476 : xTypeProvider = Reference<XTypeProvider>::query( x );
1623 9476 : if( xTypeProvider.is() )
1624 : {
1625 9466 : SupportedTypesSeq = xTypeProvider->getTypes();
1626 9466 : sal_Int32 nTypeCount = SupportedTypesSeq.getLength();
1627 9466 : if( nTypeCount )
1628 : {
1629 9466 : SupportedClassSeq.realloc( nTypeCount );
1630 9466 : Reference<XIdlClass>* pClasses = SupportedClassSeq.getArray();
1631 :
1632 9466 : const Type* pTypes = SupportedTypesSeq.getConstArray();
1633 481434 : for( sal_Int32 i = 0 ; i < nTypeCount ; i++ )
1634 : {
1635 471968 : pClasses[i] = reflection_->forName(pTypes[i].getTypeName());
1636 : }
1637 : // TODO: Caching!
1638 : }
1639 : } else {
1640 : SAL_WARN(
1641 : "stoc",
1642 : "object of type \"" << aToInspectObj.getValueTypeName()
1643 : << "\" lacks XTypeProvider");
1644 10 : xImplClass = reflection_->forName(aToInspectObj.getValueTypeName());
1645 10 : SupportedClassSeq.realloc(1);
1646 10 : SupportedClassSeq[0] = xImplClass;
1647 : }
1648 :
1649 9476 : xPropSet = Reference<XPropertySet>::query( x );
1650 : // Jetzt versuchen, das PropertySetInfo zu bekommen
1651 9476 : if( xPropSet.is() )
1652 6537 : xPropSetInfo = xPropSet->getPropertySetInfo();
1653 : } else {
1654 764 : xImplClass = reflection_->forName(aToInspectObj.getValueTypeName());
1655 : }
1656 :
1657 10240 : if (xTypeProvider.is()) {
1658 9466 : TypeKey key(xPropSetInfo, xTypeProvider->getTypes());
1659 9466 : pAccess = typeCache_.find(key);
1660 9466 : if (pAccess.is()) {
1661 8994 : return new ImplIntrospectionAccess(aToInspectObj, pAccess);
1662 : }
1663 472 : pAccess = new IntrospectionAccessStatic_Impl(reflection_);
1664 472 : typeCache_.insert(key, pAccess);
1665 774 : } else if (xImplClass.is()) {
1666 774 : ClassKey key(xPropSetInfo, xImplClass, SupportedClassSeq);
1667 774 : pAccess = classCache_.find(key);
1668 774 : if (pAccess.is()) {
1669 737 : return new ImplIntrospectionAccess(aToInspectObj, pAccess);
1670 : }
1671 37 : pAccess = new IntrospectionAccessStatic_Impl(reflection_);
1672 37 : classCache_.insert(key, pAccess);
1673 : }
1674 :
1675 : // Kein Access gecached -> neu anlegen
1676 : Property* pAllPropArray;
1677 : Reference<XInterface>* pInterfaces1;
1678 : Reference<XInterface>* pInterfaces2;
1679 : sal_Int16* pMapTypeArray;
1680 : sal_Int32* pPropertyConceptArray;
1681 : sal_Int32 i;
1682 :
1683 509 : if( !pAccess.is() )
1684 0 : pAccess = new IntrospectionAccessStatic_Impl( reflection_ );
1685 :
1686 : // Referenzen auf wichtige Daten von pAccess
1687 509 : sal_Int32& rPropCount = pAccess->mnPropCount;
1688 509 : IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap;
1689 509 : IntrospectionNameMap& rMethodNameMap = pAccess->maMethodNameMap;
1690 509 : LowerToExactNameMap& rLowerToExactNameMap = pAccess->maLowerToExactNameMap;
1691 :
1692 : // Schon mal Pointer auf das eigene Property-Feld holen
1693 509 : pAllPropArray = pAccess->maAllPropertySeq.getArray();
1694 509 : pInterfaces1 = pAccess->aInterfaceSeq1.getArray();
1695 509 : pInterfaces2 = pAccess->aInterfaceSeq2.getArray();
1696 509 : pMapTypeArray = pAccess->maMapTypeSeq.getArray();
1697 509 : pPropertyConceptArray = pAccess->maPropertyConceptSeq.getArray();
1698 :
1699 :
1700 : //*** Analyse vornehmen ***
1701 :
1702 509 : if( eType == TypeClass_INTERFACE )
1703 : {
1704 : // Zunaechst nach speziellen Interfaces suchen, die fuer
1705 : // die Introspection von besonderer Bedeutung sind.
1706 :
1707 : // XPropertySet vorhanden?
1708 474 : if( xPropSet.is() && xPropSetInfo.is() )
1709 : {
1710 : // Gibt es auch ein FastPropertySet?
1711 264 : Reference<XFastPropertySet> xDummy = Reference<XFastPropertySet>::query( x );
1712 264 : bool bFast = pAccess->mbFastPropSet = xDummy.is();
1713 :
1714 528 : Sequence<Property> aPropSeq = xPropSetInfo->getProperties();
1715 264 : const Property* pProps = aPropSeq.getConstArray();
1716 264 : sal_Int32 nLen = aPropSeq.getLength();
1717 :
1718 : // Bei FastPropertySet muessen wir uns die Original-Handles merken
1719 264 : if( bFast )
1720 95 : pAccess->mpOrgPropertyHandleArray = new sal_Int32[ nLen ];
1721 :
1722 12109 : for( i = 0 ; i < nLen ; i++ )
1723 : {
1724 : // Property in eigene Liste uebernehmen
1725 : pAccess->checkPropertyArraysSize
1726 11845 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
1727 11845 : Property& rProp = pAllPropArray[ rPropCount ];
1728 11845 : rProp = pProps[ i ];
1729 :
1730 11845 : if( bFast )
1731 5296 : pAccess->mpOrgPropertyHandleArray[ i ] = rProp.Handle;
1732 :
1733 : // PropCount als Handle fuer das eigene FastPropertySet eintragen
1734 11845 : rProp.Handle = rPropCount;
1735 :
1736 : // Art der Property merken
1737 11845 : pMapTypeArray[ rPropCount ] = MAP_PROPERTY_SET;
1738 11845 : pPropertyConceptArray[ rPropCount ] = PROPERTYSET;
1739 11845 : pAccess->mnPropertySetPropCount++;
1740 :
1741 : // Namen in Hashtable eintragen, wenn nicht schon bekannt
1742 11845 : OUString aPropName = rProp.Name;
1743 :
1744 : // Haben wir den Namen schon?
1745 11845 : IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
1746 11845 : if( aIt == rPropNameMap.end() )
1747 : {
1748 : // Neuer Eintrag in die Hashtable
1749 11845 : rPropNameMap[ aPropName ] = rPropCount;
1750 :
1751 : // Tabelle fuer XExactName pflegen
1752 11845 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
1753 : }
1754 : else
1755 : {
1756 : SAL_WARN( "stoc", "Introspection: Property \"" <<
1757 : aPropName << "\" found more than once in PropertySet" );
1758 : }
1759 :
1760 : // Count pflegen
1761 11845 : rPropCount++;
1762 12109 : }
1763 : }
1764 :
1765 : // Indizes in die Export-Tabellen
1766 474 : sal_Int32 iAllExportedMethod = 0;
1767 474 : sal_Int32 iAllSupportedListener = 0;
1768 :
1769 474 : std::set<OUString> seen;
1770 :
1771 : // Flag, ob XInterface-Methoden erfasst werden sollen
1772 : // (das darf nur einmal erfolgen, initial zulassen)
1773 474 : bool bXInterfaceIsInvalid = false;
1774 :
1775 : // Flag, ob die XInterface-Methoden schon erfasst wurden. Wenn sal_True,
1776 : // wird bXInterfaceIsInvalid am Ende der Iface-Schleife aktiviert und
1777 : // XInterface-Methoden werden danach abgeklemmt.
1778 474 : bool bFoundXInterface = false;
1779 :
1780 474 : sal_Int32 nClassCount = SupportedClassSeq.getLength();
1781 14023 : for( sal_Int32 nIdx = 0 ; nIdx < nClassCount; nIdx++ )
1782 : {
1783 13549 : Reference<XIdlClass> xImplClass2 = SupportedClassSeq.getConstArray()[nIdx];
1784 56769 : while( xImplClass2.is() )
1785 : {
1786 : // Interfaces der Implementation holen
1787 29671 : Sequence< Reference<XIdlClass> > aClassSeq = xImplClass2->getInterfaces();
1788 29671 : sal_Int32 nIfaceCount = aClassSeq.getLength();
1789 :
1790 29671 : aClassSeq.realloc( nIfaceCount + 1 );
1791 29671 : aClassSeq.getArray()[ nIfaceCount ] = xImplClass2;
1792 29671 : nIfaceCount++;
1793 :
1794 29671 : const Reference<XIdlClass>* pParamArray = aClassSeq.getConstArray();
1795 :
1796 59342 : for( sal_Int32 j = 0 ; j < nIfaceCount ; j++ )
1797 : {
1798 29671 : const Reference<XIdlClass>& rxIfaceClass = pParamArray[j];
1799 29671 : if (!seen.insert(rxIfaceClass->getName()).second) {
1800 15002 : continue;
1801 : }
1802 :
1803 : // 2. Fields als Properties registrieren
1804 :
1805 : // Felder holen
1806 14669 : Sequence< Reference<XIdlField> > fields = rxIfaceClass->getFields();
1807 14669 : const Reference<XIdlField>* pFields = fields.getConstArray();
1808 14669 : sal_Int32 nLen = fields.getLength();
1809 :
1810 17434 : for( i = 0 ; i < nLen ; i++ )
1811 : {
1812 2765 : Reference<XIdlField> xField = pFields[i];
1813 4443 : Reference<XIdlClass> xPropType = xField->getType();
1814 :
1815 : // Ist die PropertySequence gross genug?
1816 : pAccess->checkPropertyArraysSize
1817 2765 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
1818 :
1819 : // In eigenes Property-Array eintragen
1820 2765 : Property& rProp = pAllPropArray[ rPropCount ];
1821 4443 : OUString aFieldName = xField->getName();
1822 2765 : rProp.Name = aFieldName;
1823 2765 : rProp.Handle = rPropCount;
1824 4443 : Type aFieldType( xPropType->getTypeClass(), xPropType->getName() );
1825 2765 : rProp.Type = aFieldType;
1826 2765 : FieldAccessMode eAccessMode = xField->getAccessMode();
1827 736 : rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
1828 : eAccessMode == FieldAccessMode_CONST)
1829 4794 : ? READONLY : 0;
1830 :
1831 : // Namen in Hashtable eintragen
1832 4443 : OUString aPropName = rProp.Name;
1833 :
1834 : // Haben wir den Namen schon?
1835 2765 : IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
1836 2765 : if( !( aIt == rPropNameMap.end() ) )
1837 1087 : continue;
1838 :
1839 : // Neuer Eintrag in die Hashtable
1840 1678 : rPropNameMap[ aPropName ] = rPropCount;
1841 :
1842 : // Tabelle fuer XExactName pflegen
1843 1678 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
1844 :
1845 : // Field merken
1846 1678 : IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess->aInterfaceSeq1,
1847 3356 : pInterfaces1, rPropCount );
1848 1678 : pInterfaces1[ rPropCount ] = xField;
1849 :
1850 : // Art der Property merken
1851 1678 : pMapTypeArray[ rPropCount ] = MAP_FIELD;
1852 1678 : pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
1853 1678 : pAccess->mnAttributePropCount++;
1854 :
1855 : // Count pflegen
1856 1678 : rPropCount++;
1857 1678 : }
1858 :
1859 :
1860 :
1861 : // 3. Methoden
1862 :
1863 : // Zaehler fuer die gefundenen Listener
1864 14669 : sal_Int32 nListenerCount = 0;
1865 :
1866 : // Alle Methoden holen und merken
1867 29338 : Sequence< Reference<XIdlMethod> > methods = rxIfaceClass->getMethods();
1868 14669 : const Reference<XIdlMethod>* pSourceMethods = methods.getConstArray();
1869 14669 : sal_Int32 nSourceMethodCount = methods.getLength();
1870 :
1871 : // 3. a) get/set- und Listener-Methoden suchen
1872 :
1873 : // Feld fuer Infos ueber die Methoden anlegen, damit spaeter leicht die Methoden
1874 : // gefunden werden koennen, die nicht im Zusammenhang mit Properties oder Listenern
1875 : // stehen. NEU: auch MethodConceptArray initialisieren
1876 : enum MethodType
1877 : {
1878 : STANDARD_METHOD, // normale Methode, kein Bezug zu Properties oder Listenern
1879 : GETSET_METHOD, // gehoert zu einer get/set-Property
1880 : ADD_LISTENER_METHOD, // add-Methode einer Listener-Schnittstelle
1881 : REMOVE_LISTENER_METHOD, // remove-Methode einer Listener-Schnittstelle
1882 : INVALID_METHOD // Methode, deren Klasse nicht beruecksichtigt wird, z.B. XPropertySet
1883 : };
1884 14669 : MethodType* pMethodTypes = new MethodType[ nSourceMethodCount ];
1885 14669 : sal_Int32* pLocalMethodConcepts = new sal_Int32[ nSourceMethodCount ];
1886 108289 : for( i = 0 ; i < nSourceMethodCount ; i++ )
1887 : {
1888 93620 : pMethodTypes[ i ] = STANDARD_METHOD;
1889 93620 : pLocalMethodConcepts[ i ] = 0;
1890 : }
1891 :
1892 29338 : OUString aMethName;
1893 29338 : OUString aPropName;
1894 29338 : OUString aStartStr;
1895 108289 : for( i = 0 ; i < nSourceMethodCount ; i++ )
1896 : {
1897 : // Methode ansprechen
1898 93620 : const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
1899 93620 : sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
1900 :
1901 : // Namen besorgen
1902 93620 : aMethName = rxMethod_i->getName();
1903 :
1904 : // Methoden katalogisieren
1905 : // Alle (?) Methoden von XInterface filtern, damit z.B. nicht
1906 : // vom Scripting aus acquire oder release gerufen werden kann
1907 : rtl::OUString className(
1908 93620 : rxMethod_i->getDeclaringClass()->getName());
1909 93620 : if (className == "com.sun.star.uno.XInterface") {
1910 44007 : bFoundXInterface = true;
1911 :
1912 44007 : if( bXInterfaceIsInvalid )
1913 : {
1914 42585 : pMethodTypes[ i ] = INVALID_METHOD;
1915 42585 : continue;
1916 : }
1917 : else
1918 : {
1919 1422 : if( aMethName != "queryInterface" )
1920 : {
1921 948 : rMethodConcept_i |= MethodConcept::DANGEROUS;
1922 948 : continue;
1923 : }
1924 : }
1925 49613 : } else if (className == "com.sun.star.uno.XAggregation")
1926 : {
1927 442 : if( aMethName == "setDelegator" )
1928 : {
1929 221 : rMethodConcept_i |= MethodConcept::DANGEROUS;
1930 221 : continue;
1931 : }
1932 49171 : } else if (className
1933 : == "com.sun.star.container.XElementAccess")
1934 : {
1935 : rMethodConcept_i |= ( NAMECONTAINER |
1936 : INDEXCONTAINER |
1937 868 : ENUMERATION );
1938 48303 : } else if ((className
1939 48303 : == "com.sun.star.container.XNameContainer")
1940 96546 : || (className
1941 48243 : == "com.sun.star.container.XNameAccess"))
1942 : {
1943 954 : rMethodConcept_i |= NAMECONTAINER;
1944 47349 : } else if ((className
1945 47349 : == "com.sun.star.container.XIndexContainer")
1946 94698 : || (className
1947 47349 : == "com.sun.star.container.XIndexAccess"))
1948 : {
1949 20 : rMethodConcept_i |= INDEXCONTAINER;
1950 47329 : } else if (className
1951 : == "com.sun.star.container.XEnumerationAccess")
1952 : {
1953 45 : rMethodConcept_i |= ENUMERATION;
1954 : }
1955 :
1956 : // Wenn der Name zu kurz ist, wird's sowieso nichts
1957 49866 : if( aMethName.getLength() <= 3 )
1958 15 : continue;
1959 :
1960 : // Ist es eine get-Methode?
1961 49851 : aStartStr = aMethName.copy( 0, 3 );
1962 49851 : if( aStartStr == "get" )
1963 : {
1964 : // Namen der potentiellen Property
1965 17502 : aPropName = aMethName.copy( 3 );
1966 :
1967 : // get-Methode darf keinen Parameter haben
1968 17502 : Sequence< Reference<XIdlClass> > getParams = rxMethod_i->getParameterTypes();
1969 17502 : if( getParams.getLength() > 0 )
1970 : {
1971 5935 : continue;
1972 : }
1973 :
1974 : // Haben wir den Namen schon?
1975 11567 : IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
1976 11567 : if( !( aIt == rPropNameMap.end() ) )
1977 : {
1978 : /* TODO
1979 : OSL_TRACE(
1980 : String( "Introspection: Property \"" ) +
1981 : OOUStringToString( aPropName, CHARSET_SYSTEM ) +
1982 : String( "\" found more than once" ) );
1983 : */
1984 2301 : continue;
1985 : }
1986 :
1987 : // Eine readonly-Property ist es jetzt mindestens schon
1988 9266 : rMethodConcept_i |= PROPERTY;
1989 :
1990 9266 : pMethodTypes[i] = GETSET_METHOD;
1991 18532 : Reference<XIdlClass> xGetRetType = rxMethod_i->getReturnType();
1992 :
1993 : // Ist die PropertySequence gross genug?
1994 : pAccess->checkPropertyArraysSize
1995 9266 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
1996 :
1997 : // In eigenes Property-Array eintragen
1998 9266 : Property& rProp = pAllPropArray[ rPropCount ];
1999 9266 : rProp.Name = aPropName;
2000 9266 : rProp.Handle = rPropCount;
2001 9266 : rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
2002 9266 : rProp.Attributes = READONLY;
2003 :
2004 : // Neuer Eintrag in die Hashtable
2005 9266 : rPropNameMap[ aPropName ] = rPropCount;
2006 :
2007 : // Tabelle fuer XExactName pflegen
2008 9266 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2009 :
2010 : // get-Methode merken
2011 9266 : IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess->aInterfaceSeq1,
2012 18532 : pInterfaces1, rPropCount );
2013 9266 : pInterfaces1[ rPropCount ] = rxMethod_i;
2014 :
2015 : // Art der Property merken
2016 9266 : pMapTypeArray[ rPropCount ] = MAP_GETSET;
2017 9266 : pPropertyConceptArray[ rPropCount ] = METHODS;
2018 9266 : pAccess->mnMethodPropCount++;
2019 :
2020 : // Passende set-Methode suchen
2021 : sal_Int32 k;
2022 92045 : for( k = 0 ; k < nSourceMethodCount ; k++ )
2023 : {
2024 : // Methode ansprechen
2025 82779 : const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
2026 :
2027 : // Nur Methoden nehmen, die nicht schon zugeordnet sind
2028 82779 : if( k == i || pMethodTypes[k] != STANDARD_METHOD )
2029 126230 : continue;
2030 :
2031 : // Name holen und auswerten
2032 37910 : OUString aMethName2 = rxMethod_k->getName();
2033 39328 : OUString aStartStr2 = aMethName2.copy( 0, 3 );
2034 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2035 37910 : if( !( aStartStr2 == "set" ) )
2036 34056 : continue;
2037 :
2038 : // Ist es denn der gleiche Name?
2039 5272 : OUString aPropName2 = aMethName2.copy( 3 );
2040 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2041 3854 : if( !( aPropName == aPropName2 ) )
2042 2337 : continue;
2043 :
2044 : // set-Methode muss void returnen
2045 2935 : Reference<XIdlClass> xSetRetType = rxMethod_k->getReturnType();
2046 1517 : if( xSetRetType->getTypeClass() != TypeClass_VOID )
2047 : {
2048 66 : continue;
2049 : }
2050 :
2051 : // set-Methode darf nur einen Parameter haben
2052 2869 : Sequence< Reference<XIdlClass> > setParams = rxMethod_k->getParameterTypes();
2053 1451 : sal_Int32 nParamCount = setParams.getLength();
2054 1451 : if( nParamCount != 1 )
2055 : {
2056 33 : continue;
2057 : }
2058 :
2059 : // Jetzt muss nur noch der return-Typ dem Parameter-Typ entsprechen
2060 1418 : const Reference<XIdlClass>* pParamArray2 = setParams.getConstArray();
2061 2836 : Reference<XIdlClass> xParamType = pParamArray2[ 0 ];
2062 1418 : if( xParamType->equals( xGetRetType ) )
2063 : {
2064 1418 : pLocalMethodConcepts[ k ] = PROPERTY;
2065 :
2066 1418 : pMethodTypes[k] = GETSET_METHOD;
2067 :
2068 : // ReadOnly-Flag wieder loschen
2069 1418 : rProp.Attributes &= ~READONLY;
2070 :
2071 : // set-Methode merken
2072 1418 : IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess->aInterfaceSeq2,
2073 2836 : pInterfaces2, rPropCount );
2074 1418 : pInterfaces2[ rPropCount ] = rxMethod_k;
2075 : }
2076 1418 : }
2077 :
2078 : // Count pflegen
2079 18532 : rPropCount++;
2080 : }
2081 :
2082 : // Ist es eine addListener-Methode?
2083 32349 : else if( aStartStr == "add" )
2084 : {
2085 4638 : OUString aListenerStr( "Listener" );
2086 :
2087 : // Namen der potentiellen Property
2088 4638 : sal_Int32 nStrLen = aMethName.getLength();
2089 4638 : sal_Int32 nCopyLen = nStrLen - aListenerStr.getLength();
2090 8585 : OUString aEndStr = aMethName.copy( nCopyLen > 0 ? nCopyLen : 0 );
2091 :
2092 : // Endet das Teil auf Listener?
2093 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2094 4638 : if( !( aEndStr == aListenerStr ) )
2095 691 : continue;
2096 :
2097 : // Welcher Listener?
2098 7894 : OUString aListenerName = aMethName.copy( 3, nStrLen - aListenerStr.getLength() - 3 );
2099 :
2100 : // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
2101 : // - Rueckgabe-Typ
2102 : // - Anzahl und Art der Parameter
2103 :
2104 :
2105 : // Passende remove-Methode suchen, sonst gilt's nicht
2106 : sal_Int32 k;
2107 47680 : for( k = 0 ; k < nSourceMethodCount ; k++ )
2108 : {
2109 : // Methode ansprechen
2110 43733 : const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
2111 :
2112 : // Nur Methoden nehmen, die nicht schon zugeordnet sind
2113 43733 : if( k == i || pMethodTypes[k] != STANDARD_METHOD )
2114 59429 : continue;
2115 :
2116 : // Name holen und auswerten
2117 24090 : OUString aMethName2 = rxMethod_k->getName();
2118 24090 : sal_Int32 nNameLen = aMethName2.getLength();
2119 24090 : sal_Int32 nCopyLen2 = (nNameLen < 6) ? nNameLen : 6;
2120 28037 : OUString aStartStr2 = aMethName2.copy( 0, nCopyLen2 );
2121 28037 : OUString aRemoveStr("remove" );
2122 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2123 24090 : if( !( aStartStr2 == aRemoveStr ) )
2124 18220 : continue;
2125 :
2126 : // Ist es denn der gleiche Listener?
2127 5870 : if( aMethName2.getLength() - aRemoveStr.getLength() <= aListenerStr.getLength() )
2128 170 : continue;
2129 : OUString aListenerName2 = aMethName2.copy
2130 9647 : ( 6, aMethName2.getLength() - aRemoveStr.getLength() - aListenerStr.getLength() );
2131 : // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
2132 5700 : if( !( aListenerName == aListenerName2 ) )
2133 1753 : continue;
2134 :
2135 : // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
2136 : // - Rueckgabe-Typ
2137 : // - Anzahl und Art der Parameter
2138 :
2139 :
2140 : // Methoden sind als Listener-Schnittstelle erkannt
2141 3947 : rMethodConcept_i |= LISTENER;
2142 3947 : pLocalMethodConcepts[ k ] |= LISTENER;
2143 :
2144 3947 : pMethodTypes[i] = ADD_LISTENER_METHOD;
2145 3947 : pMethodTypes[k] = REMOVE_LISTENER_METHOD;
2146 3947 : nListenerCount++;
2147 7894 : }
2148 : }
2149 40924 : }
2150 :
2151 :
2152 : // Jetzt koennen noch SET-Methoden ohne zugehoerige GET-Methode existieren,
2153 : // diese muessen zu Write-Only-Properties gemachte werden.
2154 108289 : for( i = 0 ; i < nSourceMethodCount ; i++ )
2155 : {
2156 : // Methode ansprechen
2157 93620 : const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
2158 :
2159 : // Nur Methoden nehmen, die nicht schon zugeordnet sind
2160 93620 : if( pMethodTypes[i] != STANDARD_METHOD )
2161 61163 : continue;
2162 :
2163 : // Namen besorgen
2164 32457 : aMethName = rxMethod_i->getName();
2165 :
2166 : // Wenn der Name zu kurz ist, wird's sowieso nichts
2167 32457 : if( aMethName.getLength() <= 3 )
2168 15 : continue;
2169 :
2170 : // Ist es eine set-Methode ohne zugehoerige get-Methode?
2171 32442 : aStartStr = aMethName.copy( 0, 3 );
2172 32442 : if( aStartStr == "set" )
2173 : {
2174 : // Namen der potentiellen Property
2175 2522 : aPropName = aMethName.copy( 3 );
2176 :
2177 : // set-Methode muss void returnen
2178 2522 : Reference<XIdlClass> xSetRetType = rxMethod_i->getReturnType();
2179 2522 : if( xSetRetType->getTypeClass() != TypeClass_VOID )
2180 : {
2181 73 : continue;
2182 : }
2183 :
2184 : // set-Methode darf nur einen Parameter haben
2185 3180 : Sequence< Reference<XIdlClass> > setParams = rxMethod_i->getParameterTypes();
2186 2449 : sal_Int32 nParamCount = setParams.getLength();
2187 2449 : if( nParamCount != 1 )
2188 : {
2189 1061 : continue;
2190 : }
2191 :
2192 : // Haben wir den Namen schon?
2193 1388 : IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
2194 1388 : if( !( aIt == rPropNameMap.end() ) )
2195 : {
2196 : /* TODO:
2197 : OSL_TRACE(
2198 : String( "Introspection: Property \"" ) +
2199 : OOUStringToString( aPropName, CHARSET_SYSTEM ) +
2200 : String( "\" found more than once" ) );
2201 : */
2202 657 : continue;
2203 : }
2204 :
2205 : // Alles klar, es ist eine Write-Only-Property
2206 731 : pLocalMethodConcepts[ i ] = PROPERTY;
2207 :
2208 731 : pMethodTypes[i] = GETSET_METHOD;
2209 1462 : Reference<XIdlClass> xGetRetType = setParams.getConstArray()[0];
2210 :
2211 : // Ist die PropertySequence gross genug?
2212 : pAccess->checkPropertyArraysSize
2213 731 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2214 :
2215 : // In eigenes Property-Array eintragen
2216 731 : Property& rProp = pAllPropArray[ rPropCount ];
2217 731 : rProp.Name = aPropName;
2218 731 : rProp.Handle = rPropCount;
2219 731 : rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
2220 731 : rProp.Attributes = 0; // PROPERTY_WRITEONLY ???
2221 :
2222 : // Neuer Eintrag in die Hashtable
2223 731 : rPropNameMap[ aPropName ] = rPropCount;
2224 :
2225 : // Tabelle fuer XExactName pflegen
2226 731 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2227 :
2228 : // set-Methode merken
2229 731 : IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess->aInterfaceSeq2,
2230 1462 : pInterfaces2, rPropCount );
2231 731 : pInterfaces2[ rPropCount ] = rxMethod_i;
2232 :
2233 : // Art der Property merken
2234 731 : pMapTypeArray[ rPropCount ] = MAP_SETONLY;
2235 731 : pPropertyConceptArray[ rPropCount ] = METHODS;
2236 731 : pAccess->mnMethodPropCount++;
2237 :
2238 : // Count pflegen
2239 1462 : rPropCount++;
2240 : }
2241 : }
2242 :
2243 :
2244 :
2245 :
2246 : // 4. Methoden in die Gesamt-Sequence uebernehmen
2247 :
2248 : // Wieviele Methoden muessen in die Method-Sequence?
2249 14669 : sal_Int32 nExportedMethodCount = 0;
2250 14669 : sal_Int32 nSupportedListenerCount = 0;
2251 108289 : for( i = 0 ; i < nSourceMethodCount ; i++ )
2252 : {
2253 93620 : if( pMethodTypes[ i ] != INVALID_METHOD )
2254 : {
2255 51035 : nExportedMethodCount++;
2256 : }
2257 93620 : if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
2258 : {
2259 3947 : nSupportedListenerCount++;
2260 : }
2261 : }
2262 :
2263 : // Sequences im Access-Objekt entsprechend aufbohren
2264 14669 : pAccess->maAllMethodSeq.realloc( nExportedMethodCount + iAllExportedMethod );
2265 14669 : pAccess->maMethodConceptSeq.realloc( nExportedMethodCount + iAllExportedMethod );
2266 14669 : pAccess->maSupportedListenerSeq.realloc( nSupportedListenerCount + iAllSupportedListener );
2267 :
2268 : // Methoden reinschreiben
2269 14669 : Reference<XIdlMethod>* pDestMethods = pAccess->maAllMethodSeq.getArray();
2270 14669 : sal_Int32* pMethodConceptArray = pAccess->maMethodConceptSeq.getArray();
2271 14669 : Type* pListenerClassRefs = pAccess->maSupportedListenerSeq.getArray();
2272 108289 : for( i = 0 ; i < nSourceMethodCount ; i++ )
2273 : {
2274 93620 : if( pMethodTypes[ i ] != INVALID_METHOD )
2275 : {
2276 : // Methode ansprechen
2277 51035 : const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
2278 :
2279 : // Namen in Hashtable eintragen, wenn nicht schon bekannt
2280 51035 : OUString aMethName2 = rxMethod->getName();
2281 51035 : IntrospectionNameMap::iterator aIt = rMethodNameMap.find( aMethName2 );
2282 51035 : if( aIt == rMethodNameMap.end() )
2283 : {
2284 : // Eintragen
2285 39633 : rMethodNameMap[ aMethName2 ] = iAllExportedMethod;
2286 :
2287 : // Tabelle fuer XExactName pflegen
2288 39633 : rLowerToExactNameMap[ toLower( aMethName2 ) ] = aMethName2;
2289 : }
2290 : else
2291 : {
2292 11402 : sal_Int32 iHashResult = (*aIt).second;
2293 :
2294 11402 : Reference<XIdlMethod> xExistingMethod = pDestMethods[ iHashResult ];
2295 :
2296 : Reference< XIdlClass > xExistingMethClass =
2297 12551 : xExistingMethod->getDeclaringClass();
2298 12551 : Reference< XIdlClass > xNewMethClass = rxMethod->getDeclaringClass();
2299 11402 : if( xExistingMethClass->equals( xNewMethClass ) )
2300 11402 : continue;
2301 : }
2302 :
2303 40782 : pDestMethods[ iAllExportedMethod ] = rxMethod;
2304 :
2305 : // Wenn kein Concept gesetzt wurde, ist die Methode "normal"
2306 40782 : sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
2307 40782 : if( !rMethodConcept_i )
2308 22030 : rMethodConcept_i = MethodConcept_NORMAL_IMPL;
2309 40782 : pMethodConceptArray[ iAllExportedMethod ] = rMethodConcept_i;
2310 40782 : iAllExportedMethod++;
2311 : }
2312 83367 : if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
2313 : {
2314 : // Klasse des Listeners ermitteln
2315 3039 : const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
2316 :
2317 : // void als Default-Klasse eintragen
2318 : css::uno::Reference<css::reflection::XIdlClass>
2319 : xListenerClass(
2320 3039 : reflection_->forName(
2321 3039 : cppu::UnoType<void>::get()
2322 6078 : .getTypeName()));
2323 : // ALT: Reference<XIdlClass> xListenerClass = Void_getReflection()->getIdlClass();
2324 :
2325 : // 1. Moeglichkeit: Parameter nach einer Listener-Klasse durchsuchen
2326 : // Nachteil: Superklassen muessen rekursiv durchsucht werden
2327 6078 : Sequence< Reference<XIdlClass> > aParams = rxMethod->getParameterTypes();
2328 3039 : const Reference<XIdlClass>* pParamArray2 = aParams.getConstArray();
2329 :
2330 : css::uno::Reference<css::reflection::XIdlClass>
2331 : xEventListenerClass(
2332 3039 : reflection_->forName(
2333 : cppu::UnoType<
2334 3039 : css::lang::XEventListener>::get()
2335 9117 : .getTypeName()));
2336 : // ALT: Reference<XIdlClass> xEventListenerClass = XEventListener_getReflection()->getIdlClass();
2337 3039 : sal_Int32 nParamCount = aParams.getLength();
2338 : sal_Int32 k;
2339 3688 : for( k = 0 ; k < nParamCount ; k++ )
2340 : {
2341 3687 : const Reference<XIdlClass>& rxClass = pParamArray2[k];
2342 :
2343 : // Sind wir von einem Listener abgeleitet?
2344 17125 : if( rxClass->equals( xEventListenerClass ) ||
2345 15815 : isDerivedFrom( rxClass, xEventListenerClass ) )
2346 : {
2347 3038 : xListenerClass = rxClass;
2348 3038 : break;
2349 : }
2350 : }
2351 :
2352 : // 2. Moeglichkeit: Namen der Methode auswerden
2353 : // Nachteil: geht nicht bei Test-Listenern, die es nicht gibt
2354 : //aMethName = rxMethod->getName();
2355 : //aListenerName = aMethName.Copy( 3, aMethName.Len()-8-3 );
2356 : //Reference<XIdlClass> xListenerClass = reflection->forName( aListenerName );
2357 6078 : Type aListenerType( TypeClass_INTERFACE, xListenerClass->getName() );
2358 3039 : pListenerClassRefs[ iAllSupportedListener ] = aListenerType;
2359 6078 : iAllSupportedListener++;
2360 : }
2361 : }
2362 :
2363 : // Wenn in diesem Durchlauf XInterface-Methoden
2364 : // dabei waren, diese zukuenftig ignorieren
2365 14669 : if( bFoundXInterface )
2366 14669 : bXInterfaceIsInvalid = true;
2367 :
2368 14669 : delete[] pMethodTypes;
2369 14669 : delete[] pLocalMethodConcepts;
2370 14669 : }
2371 :
2372 : // Super-Klasse(n) vorhanden? Dann dort fortsetzen
2373 59342 : Sequence< Reference<XIdlClass> > aSuperClassSeq = xImplClass2->getSuperclasses();
2374 :
2375 : // Zur Zeit wird nur von einer Superklasse ausgegangen
2376 29671 : if( aSuperClassSeq.getLength() >= 1 )
2377 : {
2378 16122 : xImplClass2 = aSuperClassSeq.getConstArray()[0];
2379 : OSL_ENSURE( xImplClass2.is(), "super class null" );
2380 : }
2381 : else
2382 : {
2383 13549 : xImplClass2 = NULL;
2384 : }
2385 29671 : }
2386 13549 : }
2387 :
2388 : // Anzahl der exportierten Methoden uebernehmen und Sequences anpassen
2389 : // (kann abweichen, weil doppelte Methoden erst nach der Ermittlung
2390 : // von nExportedMethodCount herausgeworfen werden)
2391 474 : sal_Int32& rMethCount = pAccess->mnMethCount;
2392 474 : rMethCount = iAllExportedMethod;
2393 474 : pAccess->maAllMethodSeq.realloc( rMethCount );
2394 474 : pAccess->maMethodConceptSeq.realloc( rMethCount );
2395 :
2396 : // Groesse der Property-Sequences anpassen
2397 474 : pAccess->maAllPropertySeq.realloc( rPropCount );
2398 474 : pAccess->maPropertyConceptSeq.realloc( rPropCount );
2399 474 : pAccess->maMapTypeSeq.realloc( rPropCount );
2400 : }
2401 : // Bei structs Fields als Properties registrieren
2402 : else //if( eType == TypeClass_STRUCT )
2403 : {
2404 : // Ist es ein Interface oder eine struct?
2405 : //Reference<XIdlClass> xClassRef = aToInspectObj.getReflection()->getIdlClass();
2406 : css::uno::Reference<css::reflection::XIdlClass> xClassRef(
2407 35 : reflection_->forName(aToInspectObj.getValueTypeName()));
2408 35 : if( !xClassRef.is() )
2409 : {
2410 : SAL_WARN( "stoc", "Can't get XIdlClass from Reflection" );
2411 0 : return new ImplIntrospectionAccess(aToInspectObj, pAccess);
2412 : }
2413 :
2414 : // Felder holen
2415 70 : Sequence< Reference<XIdlField> > fields = xClassRef->getFields();
2416 35 : const Reference<XIdlField>* pFields = fields.getConstArray();
2417 35 : sal_Int32 nLen = fields.getLength();
2418 :
2419 192 : for( i = 0 ; i < nLen ; i++ )
2420 : {
2421 157 : Reference<XIdlField> xField = pFields[i];
2422 314 : Reference<XIdlClass> xPropType = xField->getType();
2423 314 : OUString aPropName = xField->getName();
2424 :
2425 : // Ist die PropertySequence gross genug?
2426 : pAccess->checkPropertyArraysSize
2427 157 : ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
2428 :
2429 : // In eigenes Property-Array eintragen
2430 157 : Property& rProp = pAllPropArray[ rPropCount ];
2431 157 : rProp.Name = aPropName;
2432 157 : rProp.Handle = rPropCount;
2433 157 : rProp.Type = Type( xPropType->getTypeClass(), xPropType->getName() );
2434 157 : FieldAccessMode eAccessMode = xField->getAccessMode();
2435 157 : rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
2436 : eAccessMode == FieldAccessMode_CONST)
2437 157 : ? READONLY : 0;
2438 :
2439 : //FieldAccessMode eAccessMode = xField->getAccessMode();
2440 : //rProp.Attributes = (eAccessMode == FieldAccessMode::READONLY || eAccessMode == CONST)
2441 : //? PropertyAttribute::READONLY : 0;
2442 :
2443 : // Namen in Hashtable eintragen
2444 157 : rPropNameMap[ aPropName ] = rPropCount;
2445 :
2446 : // Tabelle fuer XExactName pflegen
2447 157 : rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
2448 :
2449 : // Field merken
2450 157 : IntrospectionAccessStatic_Impl::checkInterfaceArraySize( pAccess->aInterfaceSeq1,
2451 314 : pInterfaces1, rPropCount );
2452 157 : pInterfaces1[ rPropCount ] = xField;
2453 :
2454 : // Art der Property merken
2455 157 : pMapTypeArray[ rPropCount ] = MAP_FIELD;
2456 157 : pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
2457 157 : pAccess->mnAttributePropCount++;
2458 :
2459 : // Count pflegen
2460 157 : rPropCount++;
2461 192 : }
2462 : }
2463 :
2464 : // Property-Sequence auf die richtige Laenge bringen
2465 509 : pAccess->maAllPropertySeq.realloc( pAccess->mnPropCount );
2466 :
2467 19907 : return new ImplIntrospectionAccess(aToInspectObj, pAccess);
2468 : }
2469 :
2470 118 : struct Instance {
2471 118 : explicit Instance(
2472 : css::uno::Reference<css::uno::XComponentContext> const & context):
2473 118 : instance(new Implementation(context))
2474 118 : {}
2475 :
2476 : rtl::Reference<cppu::OWeakObject> instance;
2477 : };
2478 :
2479 : struct Singleton:
2480 : public rtl::StaticWithArg<
2481 : Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton>
2482 : {};
2483 :
2484 : }
2485 :
2486 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
2487 119 : com_sun_star_comp_stoc_Introspection_get_implementation(
2488 : css::uno::XComponentContext * context,
2489 : css::uno::Sequence<css::uno::Any> const & arguments)
2490 : {
2491 : SAL_WARN_IF(
2492 : arguments.hasElements(), "stoc", "unexpected singleton arguments");
2493 119 : return cppu::acquire(Singleton::get(context).instance.get());
2494 : }
2495 :
2496 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|