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