LibreOffice Module comphelper (master)  1
MasterPropertySet.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 
26 
27 
28 #include <memory>
29 #include <vector>
30 
31 namespace {
32 
33 class AutoOGuardArray
34 {
35  std::vector<std::unique_ptr< osl::Guard< comphelper::SolarMutex > >> maGuardArray;
36 
37 public:
38  explicit AutoOGuardArray( sal_Int32 nNumElements );
39 
40  std::unique_ptr< osl::Guard< comphelper::SolarMutex > > & operator[] ( sal_Int32 i ) { return maGuardArray[i]; }
41 };
42 
43 }
44 
45 AutoOGuardArray::AutoOGuardArray( sal_Int32 nNumElements ) : maGuardArray(nNumElements)
46 {
47 }
48 
49 
50 using namespace ::comphelper;
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::beans;
55 
56 
57 SlaveData::SlaveData ( ChainablePropertySet *pSlave)
58 : mxSlave ( pSlave )
59 , mbInit ( false )
60 {
61 }
62 
64  throw()
65 : mpMutex ( pMutex )
66 , mnLastId ( 0 )
67 , mxInfo ( pInfo )
68 {
69 }
70 
72  throw()
73 {
74  for( const auto& rSlave : maSlaveMap )
75  delete rSlave.second;
76 }
77 
78 // XPropertySet
79 Reference< XPropertySetInfo > SAL_CALL MasterPropertySet::getPropertySetInfo( )
80 {
81  return mxInfo.get();
82 }
83 
85  throw()
86 {
87  maSlaveMap [ ++mnLastId ] = new SlaveData ( pNewSet );
88  mxInfo->add ( pNewSet->mxInfo->maMap, mnLastId );
89 }
90 
91 void SAL_CALL MasterPropertySet::setPropertyValue( const OUString& rPropertyName, const Any& rValue )
92 {
93  // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
94  std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
95  if (mpMutex)
96  xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(mpMutex) );
97 
98  PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
99 
100  if( aIter == mxInfo->maMap.end())
101  throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
102 
103  if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
104  {
105  _preSetValues();
106  _setSingleValue( *((*aIter).second->mpInfo), rValue );
107  _postSetValues();
108  }
109  else
110  {
111  ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get();
112 
113  // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
114  std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard2;
115  if (pSlave->mpMutex)
116  xMutexGuard2.reset( new osl::Guard< comphelper::SolarMutex >(pSlave->mpMutex) );
117 
118  pSlave->_preSetValues();
119  pSlave->_setSingleValue( *((*aIter).second->mpInfo), rValue );
120  pSlave->_postSetValues();
121  }
122 }
123 
124 Any SAL_CALL MasterPropertySet::getPropertyValue( const OUString& rPropertyName )
125 {
126  // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
127  std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
128  if (mpMutex)
129  xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(mpMutex) );
130 
131  PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
132 
133  if( aIter == mxInfo->maMap.end())
134  throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
135 
136  Any aAny;
137  if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
138  {
139  _preGetValues();
140  _getSingleValue( *((*aIter).second->mpInfo), aAny );
141  _postGetValues();
142  }
143  else
144  {
145  ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get();
146 
147  // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
148  std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard2;
149  if (pSlave->mpMutex)
150  xMutexGuard2.reset( new osl::Guard< comphelper::SolarMutex >(pSlave->mpMutex) );
151 
152  pSlave->_preGetValues();
153  pSlave->_getSingleValue( *((*aIter).second->mpInfo), aAny );
154  pSlave->_postGetValues();
155  }
156  return aAny;
157 }
158 
159 void SAL_CALL MasterPropertySet::addPropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& )
160 {
161  // todo
162 }
163 
164 void SAL_CALL MasterPropertySet::removePropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& )
165 {
166  // todo
167 }
168 
169 void SAL_CALL MasterPropertySet::addVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& )
170 {
171  // todo
172 }
173 
174 void SAL_CALL MasterPropertySet::removeVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& )
175 {
176  // todo
177 }
178 
179 // XMultiPropertySet
180 void SAL_CALL MasterPropertySet::setPropertyValues( const Sequence< OUString >& aPropertyNames, const Sequence< Any >& aValues )
181 {
182  // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
183  std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
184  if (mpMutex)
185  xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(mpMutex) );
186 
187  const sal_Int32 nCount = aPropertyNames.getLength();
188 
189  if( nCount != aValues.getLength() )
190  throw IllegalArgumentException();
191 
192  if( !nCount )
193  return;
194 
195  _preSetValues();
196 
197  const Any * pAny = aValues.getConstArray();
198  const OUString * pString = aPropertyNames.getConstArray();
199  PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter;
200 
206  AutoOGuardArray aOGuardArray( nCount );
207 
208  for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny )
209  {
210  aIter = mxInfo->maMap.find ( *pString );
211  if ( aIter == aEnd )
212  throw RuntimeException( *pString, static_cast< XPropertySet* >( this ) );
213 
214  if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
215  _setSingleValue( *((*aIter).second->mpInfo), *pAny );
216  else
217  {
218  SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
219  if (!pSlave->IsInit())
220  {
221  // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
222  if (pSlave->mxSlave->mpMutex)
223  aOGuardArray[i].reset( new osl::Guard< comphelper::SolarMutex >(pSlave->mxSlave->mpMutex) );
224 
225  pSlave->mxSlave->_preSetValues();
226  pSlave->SetInit ( true );
227  }
228  pSlave->mxSlave->_setSingleValue( *((*aIter).second->mpInfo), *pAny );
229  }
230  }
231 
232  _postSetValues();
233  for( const auto& rSlave : maSlaveMap )
234  {
235  if( rSlave.second->IsInit() )
236  {
237  rSlave.second->mxSlave->_postSetValues();
238  rSlave.second->SetInit( false );
239  }
240  }
241 }
242 
243 Sequence< Any > SAL_CALL MasterPropertySet::getPropertyValues( const Sequence< OUString >& aPropertyNames )
244 {
245  // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
246  std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
247  if (mpMutex)
248  xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(mpMutex) );
249 
250  const sal_Int32 nCount = aPropertyNames.getLength();
251 
252  Sequence < Any > aValues ( nCount );
253 
254  if( nCount )
255  {
256  _preGetValues();
257 
258  Any * pAny = aValues.getArray();
259  const OUString * pString = aPropertyNames.getConstArray();
260  PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter;
261 
267  AutoOGuardArray aOGuardArray( nCount );
268 
269  for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny )
270  {
271  aIter = mxInfo->maMap.find ( *pString );
272  if ( aIter == aEnd )
273  throw RuntimeException( *pString, static_cast< XPropertySet* >( this ) );
274 
275  if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
276  _getSingleValue( *((*aIter).second->mpInfo), *pAny );
277  else
278  {
279  SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
280  if (!pSlave->IsInit())
281  {
282  // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
283  if (pSlave->mxSlave->mpMutex)
284  aOGuardArray[i].reset( new osl::Guard< comphelper::SolarMutex >(pSlave->mxSlave->mpMutex) );
285 
286  pSlave->mxSlave->_preGetValues();
287  pSlave->SetInit ( true );
288  }
289  pSlave->mxSlave->_getSingleValue( *((*aIter).second->mpInfo), *pAny );
290  }
291  }
292 
293  _postSetValues();
294  for( const auto& rSlave : maSlaveMap )
295  {
296  if( rSlave.second->IsInit() )
297  {
298  rSlave.second->mxSlave->_postSetValues();
299  rSlave.second->SetInit( false );
300  }
301  }
302  }
303  return aValues;
304 }
305 
306 void SAL_CALL MasterPropertySet::addPropertiesChangeListener( const Sequence< OUString >&, const Reference< XPropertiesChangeListener >& )
307 {
308  // todo
309 }
310 
311 void SAL_CALL MasterPropertySet::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& )
312 {
313  // todo
314 }
315 
316 void SAL_CALL MasterPropertySet::firePropertiesChangeEvent( const Sequence< OUString >&, const Reference< XPropertiesChangeListener >& )
317 {
318  // todo
319 }
320 
321 // XPropertyState
322 PropertyState SAL_CALL MasterPropertySet::getPropertyState( const OUString& PropertyName )
323 {
324  PropertyDataHash::const_iterator aIter = mxInfo->maMap.find( PropertyName );
325  if( aIter == mxInfo->maMap.end())
326  throw UnknownPropertyException( PropertyName, static_cast< XPropertySet* >( this ) );
327 
328  // 0 means it's one of ours !
329  if ( (*aIter).second->mnMapId != 0 )
330  {
331  ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get();
332 
333  // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
334  std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
335  if (pSlave->mpMutex)
336  xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(pSlave->mpMutex) );
337  }
338 
339  return PropertyState_AMBIGUOUS_VALUE;
340 }
341 
342 Sequence< PropertyState > SAL_CALL MasterPropertySet::getPropertyStates( const Sequence< OUString >& rPropertyNames )
343 {
344  const sal_Int32 nCount = rPropertyNames.getLength();
345 
346  Sequence< PropertyState > aStates( nCount );
347  if( nCount )
348  {
349  PropertyState * pState = aStates.getArray();
350  const OUString * pString = rPropertyNames.getConstArray();
351  PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter;
352 
353  for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pState )
354  {
355  aIter = mxInfo->maMap.find ( *pString );
356  if ( aIter == aEnd )
357  throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) );
358 
359  // 0 means it's one of ours !
360  if ( (*aIter).second->mnMapId != 0 )
361  {
362  SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
363  if (!pSlave->IsInit())
364  {
365  pSlave->SetInit ( true );
366  }
367  }
368  }
369  for( const auto& rSlave : maSlaveMap )
370  {
371  if( rSlave.second->IsInit() )
372  {
373  rSlave.second->SetInit( false );
374  }
375  }
376  }
377  return aStates;
378 }
379 
380 void SAL_CALL MasterPropertySet::setPropertyToDefault( const OUString& rPropertyName )
381 {
382  PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
383 
384  if( aIter == mxInfo->maMap.end())
385  throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
386 }
387 
388 Any SAL_CALL MasterPropertySet::getPropertyDefault( const OUString& rPropertyName )
389 {
390  PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
391 
392  if( aIter == mxInfo->maMap.end())
393  throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
394  return Any();
395 }
396 
397 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void SAL_CALL firePropertiesChangeEvent(const css::uno::Sequence< OUString > &aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener > &xListener) override
std::map< sal_uInt8, comphelper::SlaveData * > maSlaveMap
virtual void SAL_CALL removePropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) override
virtual css::uno::Sequence< css::beans::PropertyState > SAL_CALL getPropertyStates(const css::uno::Sequence< OUString > &aPropertyName) override
virtual css::uno::Any SAL_CALL getPropertyDefault(const OUString &aPropertyName) override
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
void SetInit(bool bInit)
int nCount
virtual void _postGetValues()=0
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
void registerSlave(ChainablePropertySet *pNewSet)
virtual css::beans::PropertyState SAL_CALL getPropertyState(const OUString &PropertyName) override
virtual void SAL_CALL removePropertiesChangeListener(const css::uno::Reference< css::beans::XPropertiesChangeListener > &xListener) override
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
int i
virtual void _postSetValues()=0
virtual void _getSingleValue(const comphelper::PropertyInfo &rInfo, css::uno::Any &rValue)=0
virtual void SAL_CALL addPropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
MasterPropertySet(comphelper::MasterPropertySetInfo *pInfo, SolarMutex *pMutex)
virtual void SAL_CALL setPropertyValues(const css::uno::Sequence< OUString > &aPropertyNames, const css::uno::Sequence< css::uno::Any > &aValues) override
virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues(const css::uno::Sequence< OUString > &aPropertyNames) override
rtl::Reference< MasterPropertySetInfo > mxInfo
virtual void _preSetValues()=0
virtual void SAL_CALL addPropertiesChangeListener(const css::uno::Sequence< OUString > &aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener > &xListener) override
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual void _setSingleValue(const comphelper::PropertyInfo &rInfo, const css::uno::Any &rValue)=0
SolarMutex, needed for VCL's Application::GetSolarMutex().
Definition: solarmutex.hxx:46
rtl::Reference< ChainablePropertySet > mxSlave
virtual void _setSingleValue(const comphelper::PropertyInfo &rInfo, const css::uno::Any &rValue)=0
virtual void _preGetValues()=0
virtual void _getSingleValue(const comphelper::PropertyInfo &rInfo, css::uno::Any &rValue)=0
virtual void SAL_CALL setPropertyToDefault(const OUString &PropertyName) override