Simplify a bit
[LibreOffice.git] / comphelper / source / property / MasterPropertySet.cxx
blobbd5ce83eaa162edd49c923b5f72bf607b2e1260b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <comphelper/MasterPropertySet.hxx>
22 #include <comphelper/MasterPropertySetInfo.hxx>
23 #include <comphelper/ChainablePropertySet.hxx>
24 #include <comphelper/ChainablePropertySetInfo.hxx>
25 #include <comphelper/solarmutex.hxx>
28 #include <memory>
29 #include <vector>
30 #include <optional>
32 namespace {
34 class AutoOGuardArray
36 std::vector<std::optional< osl::Guard< comphelper::SolarMutex > >> maGuardArray;
38 public:
39 explicit AutoOGuardArray( sal_Int32 nNumElements );
41 std::optional< osl::Guard< comphelper::SolarMutex > > & operator[] ( sal_Int32 i ) { return maGuardArray[i]; }
46 AutoOGuardArray::AutoOGuardArray( sal_Int32 nNumElements ) : maGuardArray(nNumElements)
51 using namespace ::comphelper;
52 using namespace ::com::sun::star;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::lang;
55 using namespace ::com::sun::star::beans;
58 SlaveData::SlaveData ( ChainablePropertySet *pSlave)
59 : mxSlave ( pSlave )
60 , mbInit ( false )
64 MasterPropertySet::MasterPropertySet( comphelper::MasterPropertySetInfo* pInfo, comphelper::SolarMutex* pMutex )
65 noexcept
66 : mpMutex ( pMutex )
67 , mnLastId ( 0 )
68 , mxInfo ( pInfo )
72 MasterPropertySet::~MasterPropertySet()
73 noexcept
75 for( const auto& rSlave : maSlaveMap )
76 delete rSlave.second;
79 // XPropertySet
80 Reference< XPropertySetInfo > SAL_CALL MasterPropertySet::getPropertySetInfo( )
82 return mxInfo;
85 void MasterPropertySet::registerSlave ( ChainablePropertySet *pNewSet )
86 noexcept
88 maSlaveMap [ ++mnLastId ] = new SlaveData ( pNewSet );
89 mxInfo->add ( pNewSet->mxInfo->maMap, mnLastId );
92 void SAL_CALL MasterPropertySet::setPropertyValue( const OUString& rPropertyName, const Any& rValue )
94 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
95 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
96 if (mpMutex)
97 xMutexGuard.emplace( mpMutex );
99 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
101 if( aIter == mxInfo->maMap.end())
102 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
104 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
106 _preSetValues();
107 _setSingleValue( *((*aIter).second->mpInfo), rValue );
108 _postSetValues();
110 else
112 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get();
114 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
115 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard2;
116 if (pSlave->mpMutex)
117 xMutexGuard2.emplace( pSlave->mpMutex );
119 pSlave->_preSetValues();
120 pSlave->_setSingleValue( *((*aIter).second->mpInfo), rValue );
121 pSlave->_postSetValues();
125 Any SAL_CALL MasterPropertySet::getPropertyValue( const OUString& rPropertyName )
127 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
128 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
129 if (mpMutex)
130 xMutexGuard.emplace( mpMutex );
132 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
134 if( aIter == mxInfo->maMap.end())
135 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
137 Any aAny;
138 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
140 _preGetValues();
141 _getSingleValue( *((*aIter).second->mpInfo), aAny );
142 _postGetValues();
144 else
146 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get();
148 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
149 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard2;
150 if (pSlave->mpMutex)
151 xMutexGuard2.emplace( pSlave->mpMutex );
153 pSlave->_preGetValues();
154 pSlave->_getSingleValue( *((*aIter).second->mpInfo), aAny );
155 pSlave->_postGetValues();
157 return aAny;
160 void SAL_CALL MasterPropertySet::addPropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& )
162 // todo
165 void SAL_CALL MasterPropertySet::removePropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& )
167 // todo
170 void SAL_CALL MasterPropertySet::addVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& )
172 // todo
175 void SAL_CALL MasterPropertySet::removeVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& )
177 // todo
180 // XMultiPropertySet
181 void SAL_CALL MasterPropertySet::setPropertyValues( const Sequence< OUString >& aPropertyNames, const Sequence< Any >& aValues )
183 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
184 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
185 if (mpMutex)
186 xMutexGuard.emplace( mpMutex );
188 const sal_Int32 nCount = aPropertyNames.getLength();
190 if( nCount != aValues.getLength() )
191 throw IllegalArgumentException();
193 if( !nCount )
194 return;
196 _preSetValues();
198 PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter;
200 //!! have a unique_ptr to an array of OGuards in order to have the
201 //!! allocated memory properly freed (exception safe!).
202 //!! Since the array itself has unique_ptrs as members we have to use a
203 //!! helper class 'AutoOGuardArray' in order to have
204 //!! the acquired locks properly released.
205 AutoOGuardArray aOGuardArray( nCount );
207 for (sal_Int32 i = 0; i < nCount; ++i)
209 aIter = mxInfo->maMap.find(aPropertyNames[i]);
210 if ( aIter == aEnd )
211 throw RuntimeException(aPropertyNames[i], static_cast<XPropertySet*>(this));
213 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
214 _setSingleValue(*((*aIter).second->mpInfo), aValues[i]);
215 else
217 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
218 if (!pSlave->IsInit())
220 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
221 if (pSlave->mxSlave->mpMutex)
222 aOGuardArray[i].emplace( pSlave->mxSlave->mpMutex );
224 pSlave->mxSlave->_preSetValues();
225 pSlave->SetInit ( true );
227 pSlave->mxSlave->_setSingleValue(*((*aIter).second->mpInfo), aValues[i]);
231 _postSetValues();
232 for( const auto& rSlave : maSlaveMap )
234 if( rSlave.second->IsInit() )
236 rSlave.second->mxSlave->_postSetValues();
237 rSlave.second->SetInit( false );
242 Sequence< Any > SAL_CALL MasterPropertySet::getPropertyValues( const Sequence< OUString >& aPropertyNames )
244 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
245 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
246 if (mpMutex)
247 xMutexGuard.emplace( mpMutex );
249 const sal_Int32 nCount = aPropertyNames.getLength();
251 Sequence < Any > aValues ( nCount );
253 if( nCount )
255 _preGetValues();
257 Any * pAny = aValues.getArray();
258 PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter;
260 //!! have a unique_ptr to an array of OGuards in order to have the
261 //!! allocated memory properly freed (exception safe!).
262 //!! Since the array itself has unique_ptrs as members we have to use a
263 //!! helper class 'AutoOGuardArray' in order to have
264 //!! the acquired locks properly released.
265 AutoOGuardArray aOGuardArray( nCount );
267 for (sal_Int32 i = 0; i < nCount; ++i)
269 aIter = mxInfo->maMap.find(aPropertyNames[i]);
270 if ( aIter == aEnd )
271 throw RuntimeException(aPropertyNames[i], static_cast<XPropertySet*>(this));
273 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
274 _getSingleValue(*((*aIter).second->mpInfo), pAny[i]);
275 else
277 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
278 if (!pSlave->IsInit())
280 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
281 if (pSlave->mxSlave->mpMutex)
282 aOGuardArray[i].emplace( pSlave->mxSlave->mpMutex );
284 pSlave->mxSlave->_preGetValues();
285 pSlave->SetInit ( true );
287 pSlave->mxSlave->_getSingleValue(*((*aIter).second->mpInfo), pAny[i]);
291 _postSetValues();
292 for( const auto& rSlave : maSlaveMap )
294 if( rSlave.second->IsInit() )
296 rSlave.second->mxSlave->_postSetValues();
297 rSlave.second->SetInit( false );
301 return aValues;
304 void SAL_CALL MasterPropertySet::addPropertiesChangeListener( const Sequence< OUString >&, const Reference< XPropertiesChangeListener >& )
306 // todo
309 void SAL_CALL MasterPropertySet::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& )
311 // todo
314 void SAL_CALL MasterPropertySet::firePropertiesChangeEvent( const Sequence< OUString >&, const Reference< XPropertiesChangeListener >& )
316 // todo
319 // XPropertyState
320 PropertyState SAL_CALL MasterPropertySet::getPropertyState( const OUString& PropertyName )
322 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find( PropertyName );
323 if( aIter == mxInfo->maMap.end())
324 throw UnknownPropertyException( PropertyName, static_cast< XPropertySet* >( this ) );
326 // 0 means it's one of ours !
327 if ( (*aIter).second->mnMapId != 0 )
329 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get();
331 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
332 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
333 if (pSlave->mpMutex)
334 xMutexGuard.emplace( pSlave->mpMutex );
337 return PropertyState_AMBIGUOUS_VALUE;
340 Sequence< PropertyState > SAL_CALL MasterPropertySet::getPropertyStates( const Sequence< OUString >& rPropertyNames )
342 const sal_Int32 nCount = rPropertyNames.getLength();
344 Sequence< PropertyState > aStates( nCount );
345 if( nCount )
347 PropertyState * pState = aStates.getArray();
348 PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter;
350 for (sal_Int32 i = 0; i < nCount; ++i)
352 aIter = mxInfo->maMap.find(rPropertyNames[i]);
353 if ( aIter == aEnd )
354 throw UnknownPropertyException(rPropertyNames[i], static_cast<XPropertySet*>(this));
356 // 0 means it's one of ours !
357 if ( (*aIter).second->mnMapId != 0 )
359 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
360 if (!pSlave->IsInit())
362 pSlave->SetInit ( true );
366 pState[i] = PropertyState_AMBIGUOUS_VALUE;
368 for( const auto& rSlave : maSlaveMap )
370 if( rSlave.second->IsInit() )
372 rSlave.second->SetInit( false );
376 return aStates;
379 void SAL_CALL MasterPropertySet::setPropertyToDefault( const OUString& rPropertyName )
381 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
383 if( aIter == mxInfo->maMap.end())
384 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
387 Any SAL_CALL MasterPropertySet::getPropertyDefault( const OUString& rPropertyName )
389 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
391 if( aIter == mxInfo->maMap.end())
392 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
393 return Any();
396 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */