1dde7d3faSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3dde7d3faSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4dde7d3faSAndrew Rist * or more contributor license agreements. See the NOTICE file
5dde7d3faSAndrew Rist * distributed with this work for additional information
6dde7d3faSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7dde7d3faSAndrew Rist * to you under the Apache License, Version 2.0 (the
8dde7d3faSAndrew Rist * "License"); you may not use this file except in compliance
9dde7d3faSAndrew Rist * with the License. You may obtain a copy of the License at
10dde7d3faSAndrew Rist *
11dde7d3faSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12dde7d3faSAndrew Rist *
13dde7d3faSAndrew Rist * Unless required by applicable law or agreed to in writing,
14dde7d3faSAndrew Rist * software distributed under the License is distributed on an
15dde7d3faSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16dde7d3faSAndrew Rist * KIND, either express or implied. See the License for the
17dde7d3faSAndrew Rist * specific language governing permissions and limitations
18dde7d3faSAndrew Rist * under the License.
19dde7d3faSAndrew Rist *
20dde7d3faSAndrew Rist *************************************************************/
21dde7d3faSAndrew Rist
22dde7d3faSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_comphelper.hxx"
26cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
27cdf0e10cSrcweir #include <com/sun/star/lang/XTypeProvider.hpp>
28cdf0e10cSrcweir #include <cppuhelper/weakagg.hxx>
29cdf0e10cSrcweir #include <cppuhelper/interfacecontainer.hxx>
30cdf0e10cSrcweir #include <comphelper/propertysethelper.hxx>
31cdf0e10cSrcweir #include <osl/mutex.hxx>
32cdf0e10cSrcweir #include <comphelper/genericpropertyset.hxx>
33cdf0e10cSrcweir #include <comphelper/propertysetinfo.hxx>
34cdf0e10cSrcweir #include <comphelper/stl_types.hxx>
35cdf0e10cSrcweir #include <vos/mutex.hxx>
36cdf0e10cSrcweir #include <rtl/uuid.h>
37cdf0e10cSrcweir #include <boost/mem_fn.hpp>
38cdf0e10cSrcweir #include <boost/bind.hpp>
39cdf0e10cSrcweir #include <boost/utility.hpp>
40cdf0e10cSrcweir
41cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////
42cdf0e10cSrcweir
43cdf0e10cSrcweir using namespace ::rtl;
44cdf0e10cSrcweir using namespace ::osl;
45cdf0e10cSrcweir using namespace ::cppu;
46cdf0e10cSrcweir using namespace ::comphelper;
47cdf0e10cSrcweir using namespace ::com::sun::star;
48cdf0e10cSrcweir using namespace ::com::sun::star::uno;
49cdf0e10cSrcweir using namespace ::com::sun::star::beans;
50cdf0e10cSrcweir using namespace ::com::sun::star::lang;
51cdf0e10cSrcweir
52cdf0e10cSrcweir DECLARE_STL_USTRINGACCESS_MAP( Any, GenericAnyMapImpl );
53cdf0e10cSrcweir
54cdf0e10cSrcweir namespace comphelper
55cdf0e10cSrcweir {
56cdf0e10cSrcweir struct IMPL_GenericPropertySet_MutexContainer
57cdf0e10cSrcweir {
58cdf0e10cSrcweir Mutex maMutex ;
59cdf0e10cSrcweir } ;
60cdf0e10cSrcweir
61cdf0e10cSrcweir class GenericPropertySet : public OWeakAggObject,
62cdf0e10cSrcweir public XServiceInfo,
63cdf0e10cSrcweir public XTypeProvider,
64cdf0e10cSrcweir public PropertySetHelper,
65cdf0e10cSrcweir private IMPL_GenericPropertySet_MutexContainer
66cdf0e10cSrcweir {
67cdf0e10cSrcweir private:
68cdf0e10cSrcweir GenericAnyMapImpl maAnyMap;
69cdf0e10cSrcweir ::cppu::OMultiTypeInterfaceContainerHelperVar< ::rtl::OUString,UStringHash,UStringEqual> m_aListener;
70cdf0e10cSrcweir
71cdf0e10cSrcweir protected:
72cdf0e10cSrcweir virtual void _setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues ) throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException );
73cdf0e10cSrcweir virtual void _getPropertyValues( const PropertyMapEntry** ppEntries, Any* pValue ) throw( UnknownPropertyException, WrappedTargetException );
74cdf0e10cSrcweir
75cdf0e10cSrcweir public:
76cdf0e10cSrcweir GenericPropertySet( PropertySetInfo* pInfo ) throw();
77cdf0e10cSrcweir virtual ~GenericPropertySet() throw();
78cdf0e10cSrcweir
79cdf0e10cSrcweir // XInterface
80cdf0e10cSrcweir virtual Any SAL_CALL queryAggregation( const Type & rType ) throw( RuntimeException);
81cdf0e10cSrcweir virtual Any SAL_CALL queryInterface( const Type & rType ) throw( RuntimeException);
82cdf0e10cSrcweir virtual void SAL_CALL acquire() throw();
83cdf0e10cSrcweir virtual void SAL_CALL release() throw();
84cdf0e10cSrcweir
85cdf0e10cSrcweir // XTypeProvider
86cdf0e10cSrcweir virtual Sequence< Type > SAL_CALL getTypes( ) throw( RuntimeException);
87cdf0e10cSrcweir virtual Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw( RuntimeException);
88cdf0e10cSrcweir
89cdf0e10cSrcweir // XServiceInfo
90cdf0e10cSrcweir virtual rtl::OUString SAL_CALL getImplementationName() throw( RuntimeException );
91cdf0e10cSrcweir virtual sal_Bool SAL_CALL supportsService( const rtl::OUString& ServiceName ) throw( RuntimeException );
92cdf0e10cSrcweir virtual Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() throw( RuntimeException );
93cdf0e10cSrcweir
94cdf0e10cSrcweir // XPropertySet
95cdf0e10cSrcweir virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
96cdf0e10cSrcweir virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
97cdf0e10cSrcweir };
98cdf0e10cSrcweir
99cdf0e10cSrcweir }
100cdf0e10cSrcweir
101cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////
102cdf0e10cSrcweir
GenericPropertySet(PropertySetInfo * pInfo)103cdf0e10cSrcweir GenericPropertySet::GenericPropertySet( PropertySetInfo* pInfo ) throw()
104cdf0e10cSrcweir : PropertySetHelper( pInfo )
105cdf0e10cSrcweir ,m_aListener(maMutex)
106cdf0e10cSrcweir {
107cdf0e10cSrcweir }
108cdf0e10cSrcweir
~GenericPropertySet()109cdf0e10cSrcweir GenericPropertySet::~GenericPropertySet() throw()
110cdf0e10cSrcweir {
111cdf0e10cSrcweir }
addPropertyChangeListener(const::rtl::OUString & aPropertyName,const Reference<XPropertyChangeListener> & xListener)112cdf0e10cSrcweir void SAL_CALL GenericPropertySet::addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
113cdf0e10cSrcweir {
114cdf0e10cSrcweir Reference < XPropertySetInfo > xInfo = getPropertySetInfo( );
115cdf0e10cSrcweir if ( xInfo.is() )
116cdf0e10cSrcweir {
117*49b34792SHerbert Dürr if ( aPropertyName.isEmpty() )
118cdf0e10cSrcweir {
119cdf0e10cSrcweir Sequence< Property> aSeq = xInfo->getProperties();
120cdf0e10cSrcweir const Property* pIter = aSeq.getConstArray();
121cdf0e10cSrcweir const Property* pEnd = pIter + aSeq.getLength();
122cdf0e10cSrcweir for( ; pIter != pEnd ; ++pIter)
123cdf0e10cSrcweir {
124cdf0e10cSrcweir m_aListener.addInterface(pIter->Name,xListener);
125cdf0e10cSrcweir }
126cdf0e10cSrcweir }
127cdf0e10cSrcweir else if ( xInfo->hasPropertyByName(aPropertyName) )
128cdf0e10cSrcweir m_aListener.addInterface(aPropertyName,xListener);
129cdf0e10cSrcweir else
130cdf0e10cSrcweir throw UnknownPropertyException( aPropertyName, *this );
131cdf0e10cSrcweir }
132cdf0e10cSrcweir }
133cdf0e10cSrcweir
removePropertyChangeListener(const::rtl::OUString & aPropertyName,const Reference<XPropertyChangeListener> & xListener)134cdf0e10cSrcweir void SAL_CALL GenericPropertySet::removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
135cdf0e10cSrcweir {
136cdf0e10cSrcweir ResettableMutexGuard aGuard( maMutex );
137cdf0e10cSrcweir Reference < XPropertySetInfo > xInfo = getPropertySetInfo( );
138cdf0e10cSrcweir aGuard.clear();
139cdf0e10cSrcweir if ( xInfo.is() )
140cdf0e10cSrcweir {
141*49b34792SHerbert Dürr if ( aPropertyName.isEmpty() )
142cdf0e10cSrcweir {
143cdf0e10cSrcweir Sequence< Property> aSeq = xInfo->getProperties();
144cdf0e10cSrcweir const Property* pIter = aSeq.getConstArray();
145cdf0e10cSrcweir const Property* pEnd = pIter + aSeq.getLength();
146cdf0e10cSrcweir for( ; pIter != pEnd ; ++pIter)
147cdf0e10cSrcweir {
148cdf0e10cSrcweir m_aListener.removeInterface(pIter->Name,xListener);
149cdf0e10cSrcweir }
150cdf0e10cSrcweir }
151cdf0e10cSrcweir else if ( xInfo->hasPropertyByName(aPropertyName) )
152cdf0e10cSrcweir m_aListener.removeInterface(aPropertyName,xListener);
153cdf0e10cSrcweir else
154cdf0e10cSrcweir throw UnknownPropertyException( aPropertyName, *this );
155cdf0e10cSrcweir }
156cdf0e10cSrcweir }
157cdf0e10cSrcweir
_setPropertyValues(const PropertyMapEntry ** ppEntries,const Any * pValues)158cdf0e10cSrcweir void GenericPropertySet::_setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues )
159cdf0e10cSrcweir throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException )
160cdf0e10cSrcweir {
161cdf0e10cSrcweir ResettableMutexGuard aGuard( maMutex );
162cdf0e10cSrcweir
163cdf0e10cSrcweir while( *ppEntries )
164cdf0e10cSrcweir {
165cdf0e10cSrcweir const OUString aPropertyName( (*ppEntries)->mpName, (*ppEntries)->mnNameLen, RTL_TEXTENCODING_ASCII_US );
166cdf0e10cSrcweir OInterfaceContainerHelper * pHelper = m_aListener.getContainer(aPropertyName);
167cdf0e10cSrcweir
168cdf0e10cSrcweir maAnyMap[ aPropertyName ] = *pValues;
169cdf0e10cSrcweir
170cdf0e10cSrcweir if ( pHelper )
171cdf0e10cSrcweir {
172cdf0e10cSrcweir PropertyChangeEvent aEvt;
173cdf0e10cSrcweir aEvt.PropertyName = aPropertyName;
174cdf0e10cSrcweir aEvt.NewValue = *pValues;
175cdf0e10cSrcweir aGuard.clear();
176cdf0e10cSrcweir pHelper->notifyEach( &XPropertyChangeListener::propertyChange, aEvt );
177cdf0e10cSrcweir aGuard.reset();
178cdf0e10cSrcweir }
179cdf0e10cSrcweir
180cdf0e10cSrcweir ppEntries++;
181cdf0e10cSrcweir pValues++;
182cdf0e10cSrcweir }
183cdf0e10cSrcweir }
184cdf0e10cSrcweir
_getPropertyValues(const comphelper::PropertyMapEntry ** ppEntries,Any * pValue)185cdf0e10cSrcweir void GenericPropertySet::_getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, Any* pValue )
186cdf0e10cSrcweir throw( UnknownPropertyException, WrappedTargetException )
187cdf0e10cSrcweir {
188cdf0e10cSrcweir MutexGuard aGuard( maMutex );
189cdf0e10cSrcweir
190cdf0e10cSrcweir while( *ppEntries )
191cdf0e10cSrcweir {
192cdf0e10cSrcweir const OUString aPropertyName( (*ppEntries)->mpName, (*ppEntries)->mnNameLen, RTL_TEXTENCODING_ASCII_US );
193cdf0e10cSrcweir *pValue = maAnyMap[ aPropertyName ];
194cdf0e10cSrcweir
195cdf0e10cSrcweir ppEntries++;
196cdf0e10cSrcweir pValue++;
197cdf0e10cSrcweir }
198cdf0e10cSrcweir }
199cdf0e10cSrcweir
200cdf0e10cSrcweir // XInterface
201cdf0e10cSrcweir
queryInterface(const Type & rType)202cdf0e10cSrcweir Any SAL_CALL GenericPropertySet::queryInterface( const Type & rType )
203cdf0e10cSrcweir throw( RuntimeException )
204cdf0e10cSrcweir {
205cdf0e10cSrcweir return OWeakAggObject::queryInterface( rType );
206cdf0e10cSrcweir }
207cdf0e10cSrcweir
queryAggregation(const Type & rType)208cdf0e10cSrcweir Any SAL_CALL GenericPropertySet::queryAggregation( const Type & rType )
209cdf0e10cSrcweir throw(RuntimeException)
210cdf0e10cSrcweir {
211cdf0e10cSrcweir Any aAny;
212cdf0e10cSrcweir
213cdf0e10cSrcweir if( rType == ::getCppuType((const Reference< XServiceInfo >*)0) )
214cdf0e10cSrcweir aAny <<= Reference< XServiceInfo >(this);
215cdf0e10cSrcweir else if( rType == ::getCppuType((const Reference< XTypeProvider >*)0) )
216cdf0e10cSrcweir aAny <<= Reference< XTypeProvider >(this);
217cdf0e10cSrcweir else if( rType == ::getCppuType((const Reference< XPropertySet >*)0) )
218cdf0e10cSrcweir aAny <<= Reference< XPropertySet >(this);
219cdf0e10cSrcweir else if( rType == ::getCppuType((const Reference< XMultiPropertySet >*)0) )
220cdf0e10cSrcweir aAny <<= Reference< XMultiPropertySet >(this);
221cdf0e10cSrcweir else
222cdf0e10cSrcweir aAny <<= OWeakAggObject::queryAggregation( rType );
223cdf0e10cSrcweir
224cdf0e10cSrcweir return aAny;
225cdf0e10cSrcweir }
226cdf0e10cSrcweir
acquire()227cdf0e10cSrcweir void SAL_CALL GenericPropertySet::acquire() throw()
228cdf0e10cSrcweir {
229cdf0e10cSrcweir OWeakAggObject::acquire();
230cdf0e10cSrcweir }
231cdf0e10cSrcweir
release()232cdf0e10cSrcweir void SAL_CALL GenericPropertySet::release() throw()
233cdf0e10cSrcweir {
234cdf0e10cSrcweir OWeakAggObject::release();
235cdf0e10cSrcweir }
236cdf0e10cSrcweir
getTypes()237cdf0e10cSrcweir uno::Sequence< uno::Type > SAL_CALL GenericPropertySet::getTypes()
238cdf0e10cSrcweir throw (uno::RuntimeException)
239cdf0e10cSrcweir {
240cdf0e10cSrcweir uno::Sequence< uno::Type > aTypes( 5 );
241cdf0e10cSrcweir uno::Type* pTypes = aTypes.getArray();
242cdf0e10cSrcweir
243cdf0e10cSrcweir *pTypes++ = ::getCppuType((const uno::Reference< XAggregation>*)0);
244cdf0e10cSrcweir *pTypes++ = ::getCppuType((const uno::Reference< XServiceInfo>*)0);
245cdf0e10cSrcweir *pTypes++ = ::getCppuType((const uno::Reference< XTypeProvider>*)0);
246cdf0e10cSrcweir *pTypes++ = ::getCppuType((const uno::Reference< XPropertySet>*)0);
247cdf0e10cSrcweir *pTypes++ = ::getCppuType((const uno::Reference< XMultiPropertySet>*)0);
248cdf0e10cSrcweir
249cdf0e10cSrcweir return aTypes;
250cdf0e10cSrcweir }
251cdf0e10cSrcweir
getImplementationId()252cdf0e10cSrcweir uno::Sequence< sal_Int8 > SAL_CALL GenericPropertySet::getImplementationId()
253cdf0e10cSrcweir throw (uno::RuntimeException)
254cdf0e10cSrcweir {
255cdf0e10cSrcweir MutexGuard aGuard( maMutex );
256cdf0e10cSrcweir
257cdf0e10cSrcweir static uno::Sequence< sal_Int8 > aId;
258cdf0e10cSrcweir if( aId.getLength() == 0 )
259cdf0e10cSrcweir {
260cdf0e10cSrcweir aId.realloc( 16 );
261cdf0e10cSrcweir rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
262cdf0e10cSrcweir }
263cdf0e10cSrcweir return aId;
264cdf0e10cSrcweir }
265cdf0e10cSrcweir
266cdf0e10cSrcweir // XServiceInfo
267cdf0e10cSrcweir
supportsService(const OUString & ServiceName)268cdf0e10cSrcweir sal_Bool SAL_CALL GenericPropertySet::supportsService( const OUString& ServiceName ) throw(RuntimeException)
269cdf0e10cSrcweir {
270cdf0e10cSrcweir Sequence< OUString > aSNL( getSupportedServiceNames() );
271cdf0e10cSrcweir const OUString * pArray = aSNL.getConstArray();
272cdf0e10cSrcweir
273cdf0e10cSrcweir for( sal_Int32 i = 0; i < aSNL.getLength(); ++i )
274cdf0e10cSrcweir if( pArray[i] == ServiceName )
275cdf0e10cSrcweir return sal_True;
276cdf0e10cSrcweir
277cdf0e10cSrcweir return sal_False;
278cdf0e10cSrcweir }
279cdf0e10cSrcweir
getImplementationName()280cdf0e10cSrcweir OUString SAL_CALL GenericPropertySet::getImplementationName() throw( RuntimeException )
281cdf0e10cSrcweir {
282cdf0e10cSrcweir return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.comphelper.GenericPropertySet") );
283cdf0e10cSrcweir }
284cdf0e10cSrcweir
getSupportedServiceNames()285cdf0e10cSrcweir Sequence< OUString > SAL_CALL GenericPropertySet::getSupportedServiceNames( )
286cdf0e10cSrcweir throw( RuntimeException )
287cdf0e10cSrcweir {
288cdf0e10cSrcweir Sequence< OUString > aSNS( 1 );
289cdf0e10cSrcweir aSNS.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.XPropertySet" ));
290cdf0e10cSrcweir return aSNS;
291cdf0e10cSrcweir }
292cdf0e10cSrcweir
GenericPropertySet_CreateInstance(comphelper::PropertySetInfo * pInfo)293cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > comphelper::GenericPropertySet_CreateInstance( comphelper::PropertySetInfo* pInfo )
294cdf0e10cSrcweir {
295cdf0e10cSrcweir return (XPropertySet*)new GenericPropertySet( pInfo );
296cdf0e10cSrcweir }
297cdf0e10cSrcweir
298