summaryrefslogtreecommitdiff
path: root/stoc
diff options
context:
space:
mode:
Diffstat (limited to 'stoc')
-rw-r--r--stoc/source/inspect/introspection.cxx245
1 files changed, 199 insertions, 46 deletions
diff --git a/stoc/source/inspect/introspection.cxx b/stoc/source/inspect/introspection.cxx
index e6b9110b7607..cfa7085f2901 100644
--- a/stoc/source/inspect/introspection.cxx
+++ b/stoc/source/inspect/introspection.cxx
@@ -162,6 +162,7 @@ class IntrospectionAccessStatic_Impl: public salhelper::SimpleReferenceObject
{
friend class Implementation;
friend class ImplIntrospectionAccess;
+ friend class ImplIntrospectionAdapter;
// Holding CoreReflection
Reference< XIdlReflection > mxCoreReflection;
@@ -194,8 +195,16 @@ class IntrospectionAccessStatic_Impl: public salhelper::SimpleReferenceObject
sal_Int32 mnAttributePropCount;
sal_Int32 mnMethodPropCount;
- // Flag, if a FastPropertySet is supported
+ // Flags which indicate if various interfaces are present
bool mbFastPropSet;
+ bool mbPropertySet;
+ bool mbElementAccess;
+ bool mbNameAccess;
+ bool mbNameContainer;
+ bool mbIndexAccess;
+ bool mbIndexContainer;
+ bool mbEnumerationAccess;
+ bool mbIdlArray;
// Original-Handles of FastPropertySets
sal_Int32* mpOrgPropertyHandleArray;
@@ -261,6 +270,15 @@ IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlR
maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP );
mbFastPropSet = false;
+ mbPropertySet = false;
+ mbElementAccess = false;
+ mbNameAccess = false;
+ mbNameContainer = false;
+ mbIndexAccess = false;
+ mbIndexContainer = false;
+ mbEnumerationAccess = false;
+ mbIdlArray = false;
+
mpOrgPropertyHandleArray = NULL;
mnPropCount = 0;
@@ -772,6 +790,9 @@ class ImplIntrospectionAdapter :
// Objekt als Interface
Reference<XInterface> mxIface;
+ // Guards the caching of queried interfaces
+ osl::Mutex m_aMutex;
+
// Original-Interfaces des Objekts
Reference<XElementAccess> mxObjElementAccess;
Reference<XNameContainer> mxObjNameContainer;
@@ -781,6 +802,14 @@ class ImplIntrospectionAdapter :
Reference<XEnumerationAccess> mxObjEnumerationAccess;
Reference<XIdlArray> mxObjIdlArray;
+ Reference<XElementAccess> getXElementAccess();
+ Reference<XNameContainer> getXNameContainer();
+ Reference<XNameAccess> getXNameAccess();
+ Reference<XIndexContainer> getXIndexContainer();
+ Reference<XIndexAccess> getXIndexAccess();
+ Reference<XEnumerationAccess> getXEnumerationAccess();
+ Reference<XIdlArray> getXIdlArray();
+
public:
ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
const Any& obj,
@@ -861,6 +890,112 @@ public:
throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception ) SAL_OVERRIDE;
};
+Reference<XElementAccess> ImplIntrospectionAdapter::getXElementAccess()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjElementAccess.is() )
+ {
+ aGuard.clear();
+ Reference<XElementAccess> xElementAccess = Reference<XElementAccess>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjElementAccess.is() )
+ mxObjElementAccess = xElementAccess;
+ }
+ return mxObjElementAccess;
+}
+
+Reference<XNameContainer> ImplIntrospectionAdapter::getXNameContainer()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjNameContainer.is() )
+ {
+ aGuard.clear();
+ Reference<XNameContainer> xNameContainer = Reference<XNameContainer>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjNameContainer.is() )
+ mxObjNameContainer = xNameContainer;
+ }
+ return mxObjNameContainer;
+}
+
+Reference<XNameAccess> ImplIntrospectionAdapter::getXNameAccess()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjNameAccess.is() )
+ {
+ aGuard.clear();
+ Reference<XNameAccess> xNameAccess = Reference<XNameAccess>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjNameAccess.is() )
+ mxObjNameAccess = xNameAccess;
+ }
+ return mxObjNameAccess;
+}
+
+Reference<XIndexContainer> ImplIntrospectionAdapter::getXIndexContainer()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjIndexContainer.is() )
+ {
+ aGuard.clear();
+ Reference<XIndexContainer> xIndexContainer = Reference<XIndexContainer>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjIndexContainer.is() )
+ mxObjIndexContainer = xIndexContainer;
+ }
+ return mxObjIndexContainer;
+}
+
+Reference<XIndexAccess> ImplIntrospectionAdapter::getXIndexAccess()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjIndexAccess.is() )
+ {
+ aGuard.clear();
+ Reference<XIndexAccess> xIndexAccess = Reference<XIndexAccess>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjIndexAccess.is() )
+ mxObjIndexAccess = xIndexAccess;
+ }
+ return mxObjIndexAccess;
+}
+
+Reference<XEnumerationAccess> ImplIntrospectionAdapter::getXEnumerationAccess()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjEnumerationAccess.is() )
+ {
+ aGuard.clear();
+ Reference<XEnumerationAccess> xEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjEnumerationAccess.is() )
+ mxObjEnumerationAccess = xEnumerationAccess;
+ }
+ return mxObjEnumerationAccess;
+}
+
+Reference<XIdlArray> ImplIntrospectionAdapter::getXIdlArray()
+{
+ ResettableGuard< Mutex > aGuard( m_aMutex );
+
+ if( !mxObjIdlArray.is() )
+ {
+ aGuard.clear();
+ Reference<XIdlArray> xIdlArray = Reference<XIdlArray>::query( mxIface );
+ aGuard.reset();
+ if( !mxObjIdlArray.is() )
+ mxObjIdlArray = xIdlArray;
+ }
+ return mxObjIdlArray;
+}
+
+
ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
const Any& obj,
rtl::Reference< IntrospectionAccessStatic_Impl > const & pStaticImpl_ )
@@ -869,17 +1004,7 @@ ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAc
// Objekt als Interfaceholen
TypeClass eType = mrInspectedObject.getValueType().getTypeClass();
if( eType == TypeClass_INTERFACE )
- {
mxIface = *static_cast<Reference< XInterface > const *>(mrInspectedObject.getValue());
-
- mxObjElementAccess = Reference<XElementAccess>::query( mxIface );
- mxObjNameAccess = Reference<XNameAccess>::query( mxIface );
- mxObjNameContainer = Reference<XNameContainer>::query( mxIface );
- mxObjIndexAccess = Reference<XIndexAccess>::query( mxIface );
- mxObjIndexContainer = Reference<XIndexContainer>::query( mxIface );
- mxObjEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface );
- mxObjIdlArray = Reference<XIdlArray>::query( mxIface );
- }
}
// Methoden von XInterface
@@ -897,14 +1022,14 @@ Any SAL_CALL ImplIntrospectionAdapter::queryInterface( const Type& rType )
if( !aRet.hasValue() )
{
// Wrapper fuer die Objekt-Interfaces
- if( ( mxObjElementAccess.is() && (aRet = ::cppu::queryInterface
+ if( ( mpStaticImpl->mbElementAccess && (aRet = ::cppu::queryInterface
( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() )
- || ( mxObjNameAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() )
- || ( mxObjNameContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() )
- || ( mxObjIndexAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() )
- || ( mxObjIndexContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() )
- || ( mxObjEnumerationAccess .is() && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() )
- || ( mxObjIdlArray.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() )
+ || ( mpStaticImpl->mbNameAccess && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() )
+ || ( mpStaticImpl->mbNameContainer && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() )
+ || ( mpStaticImpl->mbIndexAccess && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() )
+ || ( mpStaticImpl->mbIndexContainer && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() )
+ || ( mpStaticImpl->mbEnumerationAccess && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() )
+ || ( mpStaticImpl->mbIdlArray && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() )
)
{
}
@@ -1021,121 +1146,120 @@ sal_Bool ImplIntrospectionAdapter::hasPropertyByName(const OUString& Name)
// Methoden von XElementAccess
Type ImplIntrospectionAdapter::getElementType() throw( RuntimeException, std::exception )
{
- return mxObjElementAccess->getElementType();
+ return getXElementAccess()->getElementType();
}
sal_Bool ImplIntrospectionAdapter::hasElements() throw( RuntimeException, std::exception )
{
- return mxObjElementAccess->hasElements();
+ return getXElementAccess()->hasElements();
}
// Methoden von XNameAccess
Any ImplIntrospectionAdapter::getByName(const OUString& Name)
throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
{
- return mxObjNameAccess->getByName( Name );
+ return getXNameAccess()->getByName( Name );
}
Sequence< OUString > ImplIntrospectionAdapter::getElementNames()
throw( RuntimeException, std::exception )
{
- return mxObjNameAccess->getElementNames();
+ return getXNameAccess()->getElementNames();
}
sal_Bool ImplIntrospectionAdapter::hasByName(const OUString& Name)
throw( RuntimeException, std::exception )
{
- return mxObjNameAccess->hasByName( Name );
+ return getXNameAccess()->hasByName( Name );
}
// Methoden von XNameContainer
void ImplIntrospectionAdapter::insertByName(const OUString& Name, const Any& Element)
throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception )
{
- mxObjNameContainer->insertByName( Name, Element );
+ getXNameContainer()->insertByName( Name, Element );
}
void ImplIntrospectionAdapter::replaceByName(const OUString& Name, const Any& Element)
throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
{
- mxObjNameContainer->replaceByName( Name, Element );
+ getXNameContainer()->replaceByName( Name, Element );
}
void ImplIntrospectionAdapter::removeByName(const OUString& Name)
throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
{
- mxObjNameContainer->removeByName( Name );
+ getXNameContainer()->removeByName( Name );
}
// Methoden von XIndexAccess
// Schon in XNameAccess: virtual Reference<XIdlClass> getElementType() const
sal_Int32 ImplIntrospectionAdapter::getCount() throw( RuntimeException, std::exception )
{
- return mxObjIndexAccess->getCount();
+ return getXIndexAccess()->getCount();
}
Any ImplIntrospectionAdapter::getByIndex(sal_Int32 Index)
throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
{
- return mxObjIndexAccess->getByIndex( Index );
+ return getXIndexAccess()->getByIndex( Index );
}
// Methoden von XIndexContainer
void ImplIntrospectionAdapter::insertByIndex(sal_Int32 Index, const Any& Element)
throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
{
- mxObjIndexContainer->insertByIndex( Index, Element );
+ getXIndexContainer()->insertByIndex( Index, Element );
}
void ImplIntrospectionAdapter::replaceByIndex(sal_Int32 Index, const Any& Element)
throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
{
- mxObjIndexContainer->replaceByIndex( Index, Element );
+ getXIndexContainer()->replaceByIndex( Index, Element );
}
void ImplIntrospectionAdapter::removeByIndex(sal_Int32 Index)
throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
{
- mxObjIndexContainer->removeByIndex( Index );
+ getXIndexContainer()->removeByIndex( Index );
}
// Methoden von XEnumerationAccess
// Schon in XNameAccess: virtual Reference<XIdlClass> getElementType() const;
Reference<XEnumeration> ImplIntrospectionAdapter::createEnumeration() throw( RuntimeException, std::exception )
{
- return mxObjEnumerationAccess->createEnumeration();
+ return getXEnumerationAccess()->createEnumeration();
}
// Methoden von XIdlArray
void ImplIntrospectionAdapter::realloc(Any& array, sal_Int32 length)
throw( IllegalArgumentException, RuntimeException, std::exception )
{
- mxObjIdlArray->realloc( array, length );
+ getXIdlArray()->realloc( array, length );
}
sal_Int32 ImplIntrospectionAdapter::getLen(const Any& array)
throw( IllegalArgumentException, RuntimeException, std::exception )
{
- return mxObjIdlArray->getLen( array );
+ return getXIdlArray()->getLen( array );
}
Any ImplIntrospectionAdapter::get(const Any& array, sal_Int32 index)
throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception )
{
- return mxObjIdlArray->get( array, index );
+ return getXIdlArray()->get( array, index );
}
void ImplIntrospectionAdapter::set(Any& array, sal_Int32 index, const Any& value)
throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException, std::exception )
{
- mxObjIdlArray->set( array, index, value );
+ getXIdlArray()->set( array, index, value );
}
//*** Implementation von ImplIntrospectionAccess ***
-
// Methoden von XIntrospectionAccess
sal_Int32 ImplIntrospectionAccess::getSuppliedMethodConcepts()
throw( RuntimeException, std::exception )
@@ -1347,6 +1471,7 @@ Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type
{
// Gibt es schon einen Adapter?
Reference< XInterface > xAdapter( maAdapter );
+
if( !xAdapter.is() )
{
xAdapter = *( new ImplIntrospectionAdapter( this, maInspectedObject, mpStaticImpl ) );
@@ -1620,6 +1745,7 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
Reference<XIdlClass> xImplClass;
Reference<XPropertySetInfo> xPropSetInfo;
Reference<XPropertySet> xPropSet;
+ bool bHasPropertySet = false;
// Look for interfaces XTypeProvider and PropertySet
if( eType == TypeClass_INTERFACE )
@@ -1637,7 +1763,10 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
const Type* pTypes = SupportedTypesSeq.getConstArray();
for( sal_Int32 i = 0 ; i < nTypeCount ; i++ )
{
- pClasses[i] = reflection->forName(pTypes[i].getTypeName());
+ OUString typeName( pTypes[i].getTypeName() );
+ pClasses[i] = reflection->forName( typeName );
+ if( !bHasPropertySet && typeName == "com.sun.star.beans.XPropertySet" )
+ bHasPropertySet = true;
}
// TODO: Caching!
}
@@ -1651,7 +1780,8 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
SupportedClassSeq[0] = xImplClass;
}
- xPropSet = Reference<XPropertySet>::query( x );
+ if ( bHasPropertySet )
+ xPropSet = Reference<XPropertySet>::query( x );
// Jetzt versuchen, das PropertySetInfo zu bekommen
if( xPropSet.is() )
xPropSetInfo = xPropSet->getPropertySetInfo();
@@ -1660,7 +1790,7 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
}
if (xTypeProvider.is()) {
- TypeKey key(xPropSetInfo, xTypeProvider->getTypes());
+ TypeKey key(xPropSetInfo, SupportedTypesSeq);
osl::MutexGuard g(m_aMutex);
if (rBHelper.bDisposed || rBHelper.bInDispose) {
@@ -1700,6 +1830,8 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
if( !pAccess.is() )
pAccess = new IntrospectionAccessStatic_Impl( reflection );
+ pAccess->mbPropertySet = bHasPropertySet;
+
// Referenzen auf wichtige Daten von pAccess
sal_Int32& rPropCount = pAccess->mnPropCount;
IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap;
@@ -1949,22 +2081,43 @@ css::uno::Reference<css::beans::XIntrospectionAccess> Implementation::inspect(
rMethodConcept_i |= ( NAMECONTAINER |
INDEXCONTAINER |
ENUMERATION );
+ pAccess->mbElementAccess = true;
} else if ((className
- == "com.sun.star.container.XNameContainer")
- || (className
- == "com.sun.star.container.XNameAccess"))
+ == "com.sun.star.container.XNameContainer"))
{
rMethodConcept_i |= NAMECONTAINER;
+ pAccess->mbNameContainer = true;
+ pAccess->mbNameAccess = true;
+ pAccess->mbElementAccess = true;
} else if ((className
- == "com.sun.star.container.XIndexContainer")
- || (className
- == "com.sun.star.container.XIndexAccess"))
+ == "com.sun.star.container.XNameAccess"))
+ {
+ rMethodConcept_i |= NAMECONTAINER;
+ pAccess->mbNameAccess = true;
+ pAccess->mbElementAccess = true;
+ } else if ((className
+ == "com.sun.star.container.XIndexContainer"))
{
rMethodConcept_i |= INDEXCONTAINER;
+ pAccess->mbIndexContainer = true;
+ pAccess->mbIndexAccess = true;
+ pAccess->mbElementAccess = true;
+ } else if ((className
+ == "com.sun.star.container.XIndexAccess"))
+ {
+ rMethodConcept_i |= INDEXCONTAINER;
+ pAccess->mbIndexAccess = true;
+ pAccess->mbElementAccess = true;
} else if (className
== "com.sun.star.container.XEnumerationAccess")
{
rMethodConcept_i |= ENUMERATION;
+ pAccess->mbEnumerationAccess = true;
+ pAccess->mbElementAccess = true;
+ } else if (className
+ == "com.sun.star.reflection.XIdlArray")
+ {
+ pAccess->mbIdlArray = true;
}
// Wenn der Name zu kurz ist, wird's sowieso nichts