LibreOffice Module comphelper (master)  1
genericpropertyset.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <map>
23 
24 #include <com/sun/star/lang/XServiceInfo.hpp>
25 #include <com/sun/star/lang/XTypeProvider.hpp>
26 #include <cppuhelper/weakagg.hxx>
30 #include <osl/mutex.hxx>
31 #include <rtl/ref.hxx>
34 
35 using namespace ::osl;
36 using namespace ::cppu;
37 using namespace ::comphelper;
38 using namespace ::com::sun::star;
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::beans;
41 using namespace ::com::sun::star::lang;
42 
43 namespace comphelper
44 {
45  namespace {
46 
47  struct IMPL_GenericPropertySet_MutexContainer
48  {
49  Mutex maMutex;
50  };
51 
52  class GenericPropertySet : public OWeakAggObject,
53  public XServiceInfo,
54  public XTypeProvider,
55  public PropertySetHelper,
56  private IMPL_GenericPropertySet_MutexContainer
57  {
58  private:
59  std::map<OUString, Any> maAnyMap;
61 
62  protected:
63  virtual void _setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues ) override;
64  virtual void _getPropertyValues( const PropertyMapEntry** ppEntries, Any* pValue ) override;
65 
66  public:
67  explicit GenericPropertySet( PropertySetInfo* pInfo ) throw();
68 
69  // XInterface
70  virtual Any SAL_CALL queryAggregation( const Type & rType ) override;
71  virtual Any SAL_CALL queryInterface( const Type & rType ) override;
72  virtual void SAL_CALL acquire() throw() override;
73  virtual void SAL_CALL release() throw() override;
74 
75  // XTypeProvider
76  virtual Sequence< Type > SAL_CALL getTypes( ) override;
77  virtual Sequence< sal_Int8 > SAL_CALL getImplementationId( ) override;
78 
79  // XServiceInfo
80  virtual OUString SAL_CALL getImplementationName() override;
81  virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
82  virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
83 
84  // XPropertySet
85  virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override;
86  virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override;
87  };
88 
89  }
90 }
91 
92 
93 GenericPropertySet::GenericPropertySet( PropertySetInfo* pInfo ) throw()
94 : PropertySetHelper( pInfo )
95 ,m_aListener(maMutex)
96 {
97 }
98 
99 void SAL_CALL GenericPropertySet::addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener )
100 {
101  Reference < XPropertySetInfo > xInfo = getPropertySetInfo( );
102  if ( xInfo.is() )
103  {
104  if ( aPropertyName.isEmpty() )
105  {
106  Sequence< Property> aSeq = xInfo->getProperties();
107  const Property* pIter = aSeq.getConstArray();
108  const Property* pEnd = pIter + aSeq.getLength();
109  for( ; pIter != pEnd ; ++pIter)
110  {
111  m_aListener.addInterface(pIter->Name,xListener);
112  }
113  }
114  else if ( xInfo->hasPropertyByName(aPropertyName) )
115  m_aListener.addInterface(aPropertyName,xListener);
116  else
117  throw UnknownPropertyException( aPropertyName, *this );
118  }
119 }
120 
121 void SAL_CALL GenericPropertySet::removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener )
122 {
123  ClearableMutexGuard aGuard( maMutex );
124  Reference < XPropertySetInfo > xInfo = getPropertySetInfo( );
125  aGuard.clear();
126  if ( xInfo.is() )
127  {
128  if ( aPropertyName.isEmpty() )
129  {
130  Sequence< Property> aSeq = xInfo->getProperties();
131  const Property* pIter = aSeq.getConstArray();
132  const Property* pEnd = pIter + aSeq.getLength();
133  for( ; pIter != pEnd ; ++pIter)
134  {
135  m_aListener.removeInterface(pIter->Name,xListener);
136  }
137  }
138  else if ( xInfo->hasPropertyByName(aPropertyName) )
139  m_aListener.removeInterface(aPropertyName,xListener);
140  else
141  throw UnknownPropertyException( aPropertyName, *this );
142  }
143 }
144 
145 void GenericPropertySet::_setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues )
146 {
147  ResettableMutexGuard aGuard( maMutex );
148 
149  while( *ppEntries )
150  {
151  OInterfaceContainerHelper * pHelper = m_aListener.getContainer((*ppEntries)->maName);
152 
153  maAnyMap[ (*ppEntries)->maName ] = *pValues;
154 
155  if ( pHelper )
156  {
157  PropertyChangeEvent aEvt;
158  aEvt.PropertyName = (*ppEntries)->maName;
159  aEvt.NewValue = *pValues;
160  aGuard.clear();
161  pHelper->notifyEach( &XPropertyChangeListener::propertyChange, aEvt );
162  aGuard.reset();
163  }
164 
165  ppEntries++;
166  pValues++;
167  }
168 }
169 
170 void GenericPropertySet::_getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, Any* pValue )
171 {
172  MutexGuard aGuard( maMutex );
173 
174  while( *ppEntries )
175  {
176  *pValue = maAnyMap[ (*ppEntries)->maName ];
177 
178  ppEntries++;
179  pValue++;
180  }
181 }
182 
183 // XInterface
184 
185 Any SAL_CALL GenericPropertySet::queryInterface( const Type & rType )
186 {
187  return OWeakAggObject::queryInterface( rType );
188 }
189 
190 Any SAL_CALL GenericPropertySet::queryAggregation( const Type & rType )
191 {
192  Any aAny;
193 
194  if( rType == cppu::UnoType<XServiceInfo>::get())
195  aAny <<= Reference< XServiceInfo >(this);
196  else if( rType == cppu::UnoType<XTypeProvider>::get())
197  aAny <<= Reference< XTypeProvider >(this);
198  else if( rType == cppu::UnoType<XPropertySet>::get())
199  aAny <<= Reference< XPropertySet >(this);
200  else if( rType == cppu::UnoType<XMultiPropertySet>::get())
201  aAny <<= Reference< XMultiPropertySet >(this);
202  else
203  aAny = OWeakAggObject::queryAggregation( rType );
204 
205  return aAny;
206 }
207 
208 void SAL_CALL GenericPropertySet::acquire() throw()
209 {
210  OWeakAggObject::acquire();
211 }
212 
213 void SAL_CALL GenericPropertySet::release() throw()
214 {
215  OWeakAggObject::release();
216 }
217 
218 uno::Sequence< uno::Type > SAL_CALL GenericPropertySet::getTypes()
219 {
220  return uno::Sequence {
226 }
227 
228 uno::Sequence< sal_Int8 > SAL_CALL GenericPropertySet::getImplementationId()
229 {
230  return css::uno::Sequence<sal_Int8>();
231 }
232 
233 // XServiceInfo
234 sal_Bool SAL_CALL GenericPropertySet::supportsService( const OUString& ServiceName )
235 {
236  return cppu::supportsService(this, ServiceName);
237 }
238 
239 OUString SAL_CALL GenericPropertySet::getImplementationName()
240 {
241  return "com.sun.star.comp.comphelper.GenericPropertySet";
242 }
243 
244 Sequence< OUString > SAL_CALL GenericPropertySet::getSupportedServiceNames( )
245 {
246  return { "com.sun.star.beans.XPropertySet" };
247 }
248 
249 css::uno::Reference< css::beans::XPropertySet > comphelper::GenericPropertySet_CreateInstance( comphelper::PropertySetInfo* pInfo )
250 {
251  return static_cast<XPropertySet*>(new GenericPropertySet( pInfo ));
252 }
253 
254 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Type
Mutex maMutex
signed char sal_Int8
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
std::map< OUString, Any > maAnyMap
sal_Int32 SAL_CALL removeInterface(const key &rKey, const css::uno::Reference< css::uno::XInterface > &rxIFace)
this class implements a XPropertySetInfo that is initialized with arrays of PropertyMapEntry.
class SAL_NO_VTABLE XPropertySet
COMPHELPER_DLLPUBLIC css::uno::Reference< css::beans::XPropertySet > GenericPropertySet_CreateInstance(PropertySetInfo *pInfo)
unsigned char sal_Bool
std::pair< OUString const, DataAccessDescriptorProperty > PropertyMapEntry
css::uno::Type const & get()
sal_Int32 SAL_CALL addInterface(const key &rKey, const css::uno::Reference< css::uno::XInterface > &r)
Sequence< sal_Int8 > aSeq
cppu::OMultiTypeInterfaceContainerHelperVar< OUString > m_aListener
OInterfaceContainerHelper *SAL_CALL getContainer(const key &) const
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)