xref: /trunk/main/comphelper/source/property/genericpropertyset.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 );
73         virtual void _getPropertyValues( const PropertyMapEntry** ppEntries,  Any* pValue );
74 
75     public:
76         GenericPropertySet( PropertySetInfo* pInfo ) throw();
77         virtual ~GenericPropertySet() throw();
78 
79         // XInterface
80         virtual  Any SAL_CALL queryAggregation( const  Type & rType );
81         virtual  Any SAL_CALL queryInterface( const  Type & rType );
82         virtual void SAL_CALL acquire() throw();
83         virtual void SAL_CALL release() throw();
84 
85         // XTypeProvider
86         virtual  Sequence<  Type > SAL_CALL getTypes(  );
87         virtual  Sequence< sal_Int8 > SAL_CALL getImplementationId(  );
88 
89         // XServiceInfo
90         virtual rtl::OUString SAL_CALL getImplementationName();
91         virtual sal_Bool SAL_CALL supportsService( const rtl::OUString& ServiceName );
92         virtual  Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames();
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 );
96         virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener );
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 )
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 )
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 {
160     ResettableMutexGuard aGuard( maMutex );
161 
162     while( *ppEntries )
163     {
164         const OUString aPropertyName( (*ppEntries)->mpName, (*ppEntries)->mnNameLen, RTL_TEXTENCODING_ASCII_US );
165         OInterfaceContainerHelper * pHelper = m_aListener.getContainer(aPropertyName);
166 
167         maAnyMap[ aPropertyName ] = *pValues;
168 
169         if ( pHelper )
170         {
171             PropertyChangeEvent aEvt;
172             aEvt.PropertyName = aPropertyName;
173             aEvt.NewValue = *pValues;
174             aGuard.clear();
175             pHelper->notifyEach( &XPropertyChangeListener::propertyChange, aEvt );
176             aGuard.reset();
177         }
178 
179         ppEntries++;
180         pValues++;
181     }
182 }
183 
_getPropertyValues(const comphelper::PropertyMapEntry ** ppEntries,Any * pValue)184 void GenericPropertySet::_getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, Any* pValue )
185 {
186     MutexGuard aGuard( maMutex );
187 
188     while( *ppEntries )
189     {
190         const OUString aPropertyName( (*ppEntries)->mpName, (*ppEntries)->mnNameLen, RTL_TEXTENCODING_ASCII_US );
191         *pValue = maAnyMap[ aPropertyName ];
192 
193         ppEntries++;
194         pValue++;
195     }
196 }
197 
198 // XInterface
199 
queryInterface(const Type & rType)200 Any SAL_CALL GenericPropertySet::queryInterface( const Type & rType )
201 {
202     return OWeakAggObject::queryInterface( rType );
203 }
204 
queryAggregation(const Type & rType)205 Any SAL_CALL GenericPropertySet::queryAggregation( const Type & rType )
206 {
207     Any aAny;
208 
209     if( rType == ::getCppuType((const Reference< XServiceInfo >*)0) )
210         aAny <<= Reference< XServiceInfo >(this);
211     else if( rType == ::getCppuType((const Reference< XTypeProvider >*)0) )
212         aAny <<= Reference< XTypeProvider >(this);
213     else if( rType == ::getCppuType((const Reference< XPropertySet >*)0) )
214         aAny <<= Reference< XPropertySet >(this);
215     else if( rType == ::getCppuType((const Reference< XMultiPropertySet >*)0) )
216         aAny <<= Reference< XMultiPropertySet >(this);
217     else
218         aAny <<= OWeakAggObject::queryAggregation( rType );
219 
220     return aAny;
221 }
222 
acquire()223 void SAL_CALL GenericPropertySet::acquire() throw()
224 {
225     OWeakAggObject::acquire();
226 }
227 
release()228 void SAL_CALL GenericPropertySet::release() throw()
229 {
230     OWeakAggObject::release();
231 }
232 
getTypes()233 uno::Sequence< uno::Type > SAL_CALL GenericPropertySet::getTypes()
234 {
235     uno::Sequence< uno::Type > aTypes( 5 );
236     uno::Type* pTypes = aTypes.getArray();
237 
238     *pTypes++ = ::getCppuType((const uno::Reference< XAggregation>*)0);
239     *pTypes++ = ::getCppuType((const uno::Reference< XServiceInfo>*)0);
240     *pTypes++ = ::getCppuType((const uno::Reference< XTypeProvider>*)0);
241     *pTypes++ = ::getCppuType((const uno::Reference< XPropertySet>*)0);
242     *pTypes++ = ::getCppuType((const uno::Reference< XMultiPropertySet>*)0);
243 
244     return aTypes;
245 }
246 
getImplementationId()247 uno::Sequence< sal_Int8 > SAL_CALL GenericPropertySet::getImplementationId()
248 {
249     MutexGuard aGuard( maMutex );
250 
251     static uno::Sequence< sal_Int8 > aId;
252     if( aId.getLength() == 0 )
253     {
254         aId.realloc( 16 );
255         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
256     }
257     return aId;
258 }
259 
260 // XServiceInfo
261 
supportsService(const OUString & ServiceName)262 sal_Bool SAL_CALL GenericPropertySet::supportsService( const  OUString& ServiceName )
263 {
264     Sequence< OUString > aSNL( getSupportedServiceNames() );
265     const OUString * pArray = aSNL.getConstArray();
266 
267     for( sal_Int32 i = 0; i < aSNL.getLength(); ++i )
268         if( pArray[i] == ServiceName )
269             return sal_True;
270 
271     return sal_False;
272 }
273 
getImplementationName()274 OUString SAL_CALL GenericPropertySet::getImplementationName()
275 {
276     return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.comphelper.GenericPropertySet") );
277 }
278 
getSupportedServiceNames()279 Sequence< OUString > SAL_CALL GenericPropertySet::getSupportedServiceNames(  )
280 {
281     Sequence< OUString > aSNS( 1 );
282     aSNS.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.XPropertySet" ));
283     return aSNS;
284 }
285 
GenericPropertySet_CreateInstance(comphelper::PropertySetInfo * pInfo)286 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > comphelper::GenericPropertySet_CreateInstance( comphelper::PropertySetInfo* pInfo )
287 {
288     return (XPropertySet*)new GenericPropertySet( pInfo );
289 }
290