1*dde7d3faSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*dde7d3faSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*dde7d3faSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*dde7d3faSAndrew Rist  * distributed with this work for additional information
6*dde7d3faSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*dde7d3faSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*dde7d3faSAndrew Rist  * "License"); you may not use this file except in compliance
9*dde7d3faSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*dde7d3faSAndrew Rist  *
11*dde7d3faSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*dde7d3faSAndrew Rist  *
13*dde7d3faSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*dde7d3faSAndrew Rist  * software distributed under the License is distributed on an
15*dde7d3faSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*dde7d3faSAndrew Rist  * KIND, either express or implied.  See the License for the
17*dde7d3faSAndrew Rist  * specific language governing permissions and limitations
18*dde7d3faSAndrew Rist  * under the License.
19*dde7d3faSAndrew Rist  *
20*dde7d3faSAndrew Rist  *************************************************************/
21*dde7d3faSAndrew Rist 
22*dde7d3faSAndrew 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 
103cdf0e10cSrcweir GenericPropertySet::GenericPropertySet( PropertySetInfo* pInfo ) throw()
104cdf0e10cSrcweir : PropertySetHelper( pInfo )
105cdf0e10cSrcweir ,m_aListener(maMutex)
106cdf0e10cSrcweir {
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir GenericPropertySet::~GenericPropertySet() throw()
110cdf0e10cSrcweir {
111cdf0e10cSrcweir }
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     {
117cdf0e10cSrcweir         if ( !aPropertyName.getLength() )
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 
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     {
141cdf0e10cSrcweir         if ( !aPropertyName.getLength() )
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 
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 
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 
202cdf0e10cSrcweir Any SAL_CALL GenericPropertySet::queryInterface( const Type & rType )
203cdf0e10cSrcweir 	throw( RuntimeException )
204cdf0e10cSrcweir {
205cdf0e10cSrcweir 	return OWeakAggObject::queryInterface( rType );
206cdf0e10cSrcweir }
207cdf0e10cSrcweir 
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 
227cdf0e10cSrcweir void SAL_CALL GenericPropertySet::acquire() throw()
228cdf0e10cSrcweir {
229cdf0e10cSrcweir 	OWeakAggObject::acquire();
230cdf0e10cSrcweir }
231cdf0e10cSrcweir 
232cdf0e10cSrcweir void SAL_CALL GenericPropertySet::release() throw()
233cdf0e10cSrcweir {
234cdf0e10cSrcweir 	OWeakAggObject::release();
235cdf0e10cSrcweir }
236cdf0e10cSrcweir 
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 
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 
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 
280cdf0e10cSrcweir OUString SAL_CALL GenericPropertySet::getImplementationName() throw( RuntimeException )
281cdf0e10cSrcweir {
282cdf0e10cSrcweir 	return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.comphelper.GenericPropertySet") );
283cdf0e10cSrcweir }
284cdf0e10cSrcweir 
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 
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