xref: /trunk/main/comphelper/source/property/genericpropertyset.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb) !
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
30 #include <com/sun/star/lang/XServiceInfo.hpp>
31 #include <com/sun/star/lang/XTypeProvider.hpp>
32 #include <cppuhelper/weakagg.hxx>
33 #include <cppuhelper/interfacecontainer.hxx>
34 #include <comphelper/propertysethelper.hxx>
35 #include <osl/mutex.hxx>
36 #include <comphelper/genericpropertyset.hxx>
37 #include <comphelper/propertysetinfo.hxx>
38 #include <comphelper/stl_types.hxx>
39 #include <vos/mutex.hxx>
40 #include <rtl/uuid.h>
41 #include <boost/mem_fn.hpp>
42 #include <boost/bind.hpp>
43 #include <boost/utility.hpp>
44 
45 ///////////////////////////////////////////////////////////////////////
46 
47 using namespace ::rtl;
48 using namespace ::osl;
49 using namespace ::cppu;
50 using namespace ::comphelper;
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::beans;
54 using namespace ::com::sun::star::lang;
55 
56 DECLARE_STL_USTRINGACCESS_MAP( Any, GenericAnyMapImpl );
57 
58 namespace comphelper
59 {
60     struct IMPL_GenericPropertySet_MutexContainer
61     {
62         Mutex maMutex ;
63     } ;
64 
65     class GenericPropertySet :  public OWeakAggObject,
66                                 public XServiceInfo,
67                                 public XTypeProvider,
68                                 public PropertySetHelper,
69                                 private IMPL_GenericPropertySet_MutexContainer
70     {
71     private:
72         GenericAnyMapImpl   maAnyMap;
73         ::cppu::OMultiTypeInterfaceContainerHelperVar< ::rtl::OUString,UStringHash,UStringEqual> m_aListener;
74 
75     protected:
76         virtual void _setPropertyValues( const PropertyMapEntry** ppEntries, const  Any* pValues ) throw( UnknownPropertyException,  PropertyVetoException,  IllegalArgumentException,  WrappedTargetException );
77         virtual void _getPropertyValues( const PropertyMapEntry** ppEntries,  Any* pValue ) throw( UnknownPropertyException,  WrappedTargetException );
78 
79     public:
80         GenericPropertySet( PropertySetInfo* pInfo ) throw();
81         virtual ~GenericPropertySet() throw();
82 
83         // XInterface
84         virtual  Any SAL_CALL queryAggregation( const  Type & rType ) throw( RuntimeException);
85         virtual  Any SAL_CALL queryInterface( const  Type & rType ) throw( RuntimeException);
86         virtual void SAL_CALL acquire() throw();
87         virtual void SAL_CALL release() throw();
88 
89         // XTypeProvider
90         virtual  Sequence<  Type > SAL_CALL getTypes(  ) throw( RuntimeException);
91         virtual  Sequence< sal_Int8 > SAL_CALL getImplementationId(  ) throw( RuntimeException);
92 
93         // XServiceInfo
94         virtual rtl::OUString SAL_CALL getImplementationName() throw(  RuntimeException );
95         virtual sal_Bool SAL_CALL supportsService( const rtl::OUString& ServiceName ) throw(  RuntimeException );
96         virtual  Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() throw(  RuntimeException );
97 
98         // XPropertySet
99         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);
100         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);
101     };
102 
103 }
104 
105 ///////////////////////////////////////////////////////////////////////
106 
107 GenericPropertySet::GenericPropertySet( PropertySetInfo* pInfo ) throw()
108 : PropertySetHelper( pInfo )
109 ,m_aListener(maMutex)
110 {
111 }
112 
113 GenericPropertySet::~GenericPropertySet() throw()
114 {
115 }
116 void SAL_CALL GenericPropertySet::addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
117 {
118     Reference < XPropertySetInfo > xInfo = getPropertySetInfo(  );
119     if ( xInfo.is() )
120     {
121         if ( !aPropertyName.getLength() )
122         {
123             Sequence< Property> aSeq = xInfo->getProperties();
124             const Property* pIter = aSeq.getConstArray();
125             const Property* pEnd  = pIter + aSeq.getLength();
126             for( ; pIter != pEnd ; ++pIter)
127             {
128                 m_aListener.addInterface(pIter->Name,xListener);
129             }
130         }
131         else if ( xInfo->hasPropertyByName(aPropertyName) )
132             m_aListener.addInterface(aPropertyName,xListener);
133         else
134             throw UnknownPropertyException( aPropertyName, *this );
135     }
136 }
137 
138 void SAL_CALL GenericPropertySet::removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
139 {
140     ResettableMutexGuard aGuard( maMutex );
141     Reference < XPropertySetInfo > xInfo = getPropertySetInfo(  );
142     aGuard.clear();
143     if ( xInfo.is() )
144     {
145         if ( !aPropertyName.getLength() )
146         {
147             Sequence< Property> aSeq = xInfo->getProperties();
148             const Property* pIter = aSeq.getConstArray();
149             const Property* pEnd  = pIter + aSeq.getLength();
150             for( ; pIter != pEnd ; ++pIter)
151             {
152                 m_aListener.removeInterface(pIter->Name,xListener);
153             }
154         }
155         else if ( xInfo->hasPropertyByName(aPropertyName) )
156             m_aListener.removeInterface(aPropertyName,xListener);
157         else
158             throw UnknownPropertyException( aPropertyName, *this );
159     }
160 }
161 
162 void GenericPropertySet::_setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues )
163     throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException )
164 {
165     ResettableMutexGuard aGuard( maMutex );
166 
167     while( *ppEntries )
168     {
169         const OUString aPropertyName( (*ppEntries)->mpName, (*ppEntries)->mnNameLen, RTL_TEXTENCODING_ASCII_US );
170         OInterfaceContainerHelper * pHelper = m_aListener.getContainer(aPropertyName);
171 
172         maAnyMap[ aPropertyName ] = *pValues;
173 
174         if ( pHelper )
175         {
176             PropertyChangeEvent aEvt;
177             aEvt.PropertyName = aPropertyName;
178             aEvt.NewValue = *pValues;
179             aGuard.clear();
180             pHelper->notifyEach( &XPropertyChangeListener::propertyChange, aEvt );
181             aGuard.reset();
182         }
183 
184         ppEntries++;
185         pValues++;
186     }
187 }
188 
189 void GenericPropertySet::_getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, Any* pValue )
190     throw( UnknownPropertyException, WrappedTargetException )
191 {
192     MutexGuard aGuard( maMutex );
193 
194     while( *ppEntries )
195     {
196         const OUString aPropertyName( (*ppEntries)->mpName, (*ppEntries)->mnNameLen, RTL_TEXTENCODING_ASCII_US );
197         *pValue = maAnyMap[ aPropertyName ];
198 
199         ppEntries++;
200         pValue++;
201     }
202 }
203 
204 // XInterface
205 
206 Any SAL_CALL GenericPropertySet::queryInterface( const Type & rType )
207     throw( RuntimeException )
208 {
209     return OWeakAggObject::queryInterface( rType );
210 }
211 
212 Any SAL_CALL GenericPropertySet::queryAggregation( const Type & rType )
213     throw(RuntimeException)
214 {
215     Any aAny;
216 
217     if( rType == ::getCppuType((const Reference< XServiceInfo >*)0) )
218         aAny <<= Reference< XServiceInfo >(this);
219     else if( rType == ::getCppuType((const Reference< XTypeProvider >*)0) )
220         aAny <<= Reference< XTypeProvider >(this);
221     else if( rType == ::getCppuType((const Reference< XPropertySet >*)0) )
222         aAny <<= Reference< XPropertySet >(this);
223     else if( rType == ::getCppuType((const Reference< XMultiPropertySet >*)0) )
224         aAny <<= Reference< XMultiPropertySet >(this);
225     else
226         aAny <<= OWeakAggObject::queryAggregation( rType );
227 
228     return aAny;
229 }
230 
231 void SAL_CALL GenericPropertySet::acquire() throw()
232 {
233     OWeakAggObject::acquire();
234 }
235 
236 void SAL_CALL GenericPropertySet::release() throw()
237 {
238     OWeakAggObject::release();
239 }
240 
241 uno::Sequence< uno::Type > SAL_CALL GenericPropertySet::getTypes()
242     throw (uno::RuntimeException)
243 {
244     uno::Sequence< uno::Type > aTypes( 5 );
245     uno::Type* pTypes = aTypes.getArray();
246 
247     *pTypes++ = ::getCppuType((const uno::Reference< XAggregation>*)0);
248     *pTypes++ = ::getCppuType((const uno::Reference< XServiceInfo>*)0);
249     *pTypes++ = ::getCppuType((const uno::Reference< XTypeProvider>*)0);
250     *pTypes++ = ::getCppuType((const uno::Reference< XPropertySet>*)0);
251     *pTypes++ = ::getCppuType((const uno::Reference< XMultiPropertySet>*)0);
252 
253     return aTypes;
254 }
255 
256 uno::Sequence< sal_Int8 > SAL_CALL GenericPropertySet::getImplementationId()
257     throw (uno::RuntimeException)
258 {
259     MutexGuard aGuard( maMutex );
260 
261     static uno::Sequence< sal_Int8 > aId;
262     if( aId.getLength() == 0 )
263     {
264         aId.realloc( 16 );
265         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
266     }
267     return aId;
268 }
269 
270 // XServiceInfo
271 
272 sal_Bool SAL_CALL GenericPropertySet::supportsService( const  OUString& ServiceName ) throw(RuntimeException)
273 {
274     Sequence< OUString > aSNL( getSupportedServiceNames() );
275     const OUString * pArray = aSNL.getConstArray();
276 
277     for( sal_Int32 i = 0; i < aSNL.getLength(); ++i )
278         if( pArray[i] == ServiceName )
279             return sal_True;
280 
281     return sal_False;
282 }
283 
284 OUString SAL_CALL GenericPropertySet::getImplementationName() throw( RuntimeException )
285 {
286     return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.comphelper.GenericPropertySet") );
287 }
288 
289 Sequence< OUString > SAL_CALL GenericPropertySet::getSupportedServiceNames(  )
290     throw( RuntimeException )
291 {
292     Sequence< OUString > aSNS( 1 );
293     aSNS.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.XPropertySet" ));
294     return aSNS;
295 }
296 
297 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > comphelper::GenericPropertySet_CreateInstance( comphelper::PropertySetInfo* pInfo )
298 {
299     return (XPropertySet*)new GenericPropertySet( pInfo );
300 }
301 
302