merged tag ooo/OOO330_m14
[LibreOffice.git] / comphelper / source / property / MasterPropertySet.cxx
blob28078a8019fc26a0f816fb4bd66a825dc1f634af
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
31 #ifndef _COMPHELPER_MASTERPROPERTYSET_HXX_
32 #include <comphelper/MasterPropertySet.hxx>
33 #endif
34 #include <comphelper/MasterPropertySetInfo.hxx>
35 #include <comphelper/ChainablePropertySet.hxx>
36 #include <comphelper/ChainablePropertySetInfo.hxx>
37 #include <vos/mutex.hxx>
39 #include <memory> // STL auto_ptr
41 //////////////////////////////////////////////////////////////////////
43 class AutoOGuardArray
45 sal_Int32 nSize;
46 std::auto_ptr< vos::OGuard > * pGuardArray;
48 public:
49 AutoOGuardArray( sal_Int32 nNumElements );
50 ~AutoOGuardArray();
52 std::auto_ptr< vos::OGuard > & operator[] ( sal_Int32 i ) { return pGuardArray[i]; }
55 AutoOGuardArray::AutoOGuardArray( sal_Int32 nNumElements )
57 nSize = nNumElements;
58 pGuardArray = new std::auto_ptr< vos::OGuard >[ nSize ];
61 AutoOGuardArray::~AutoOGuardArray()
63 //!! release auto_ptr's and thus the mutexes locks
64 delete [] pGuardArray;
68 //////////////////////////////////////////////////////////////////////
70 using namespace ::rtl;
71 using namespace ::comphelper;
72 using namespace ::com::sun::star;
73 using namespace ::com::sun::star::uno;
74 using namespace ::com::sun::star::lang;
75 using namespace ::com::sun::star::beans;
76 using vos::IMutex;
78 SlaveData::SlaveData ( ChainablePropertySet *pSlave)
79 : mpSlave ( pSlave )
80 , mxSlave ( pSlave )
81 , mbInit ( sal_False )
85 MasterPropertySet::MasterPropertySet( comphelper::MasterPropertySetInfo* pInfo, IMutex *pMutex )
86 throw()
87 : mpInfo ( pInfo )
88 , mpMutex ( pMutex )
89 , mnLastId ( 0 )
90 , mxInfo ( pInfo )
94 void MasterPropertySet::lockMutex()
96 if (mpMutex)
97 mpMutex->acquire();
99 void MasterPropertySet::unlockMutex()
101 if (mpMutex)
102 mpMutex->release();
105 MasterPropertySet::~MasterPropertySet()
106 throw()
108 SlaveMap::iterator aEnd = maSlaveMap.end(), aIter = maSlaveMap.begin();
109 while (aIter != aEnd )
111 delete (*aIter).second;
112 aIter++;
116 // XPropertySet
117 Reference< XPropertySetInfo > SAL_CALL MasterPropertySet::getPropertySetInfo( )
118 throw(RuntimeException)
120 return mxInfo;
123 void MasterPropertySet::registerSlave ( ChainablePropertySet *pNewSet )
124 throw()
126 maSlaveMap [ ++mnLastId ] = new SlaveData ( pNewSet );
127 mpInfo->add ( pNewSet->mpInfo->maMap, mnLastId );
130 void SAL_CALL MasterPropertySet::setPropertyValue( const ::rtl::OUString& rPropertyName, const Any& rValue )
131 throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
133 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
134 std::auto_ptr< vos::OGuard > pMutexGuard;
135 if (mpMutex)
136 pMutexGuard.reset( new vos::OGuard(mpMutex) );
138 PropertyDataHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName );
140 if( aIter == mpInfo->maMap.end())
141 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
143 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
145 _preSetValues();
146 _setSingleValue( *((*aIter).second->mpInfo), rValue );
147 _postSetValues();
149 else
151 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mpSlave;
153 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
154 std::auto_ptr< vos::OGuard > pMutexGuard2;
155 if (pSlave->mpMutex)
156 pMutexGuard2.reset( new vos::OGuard(pSlave->mpMutex) );
158 pSlave->_preSetValues();
159 pSlave->_setSingleValue( *((*aIter).second->mpInfo), rValue );
160 pSlave->_postSetValues();
164 Any SAL_CALL MasterPropertySet::getPropertyValue( const ::rtl::OUString& rPropertyName )
165 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
167 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
168 std::auto_ptr< vos::OGuard > pMutexGuard;
169 if (mpMutex)
170 pMutexGuard.reset( new vos::OGuard(mpMutex) );
172 PropertyDataHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName );
174 if( aIter == mpInfo->maMap.end())
175 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
177 Any aAny;
178 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
180 _preGetValues();
181 _getSingleValue( *((*aIter).second->mpInfo), aAny );
182 _postGetValues();
184 else
186 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mpSlave;
188 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
189 std::auto_ptr< vos::OGuard > pMutexGuard2;
190 if (pSlave->mpMutex)
191 pMutexGuard2.reset( new vos::OGuard(pSlave->mpMutex) );
193 pSlave->_preGetValues();
194 pSlave->_getSingleValue( *((*aIter).second->mpInfo), aAny );
195 pSlave->_postGetValues();
197 return aAny;
200 void SAL_CALL MasterPropertySet::addPropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& )
201 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
203 // todo
206 void SAL_CALL MasterPropertySet::removePropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& )
207 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
209 // todo
212 void SAL_CALL MasterPropertySet::addVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& )
213 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
215 // todo
218 void SAL_CALL MasterPropertySet::removeVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& )
219 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
221 // todo
224 // XMultiPropertySet
225 void SAL_CALL MasterPropertySet::setPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames, const Sequence< Any >& aValues )
226 throw(PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
228 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
229 std::auto_ptr< vos::OGuard > pMutexGuard;
230 if (mpMutex)
231 pMutexGuard.reset( new vos::OGuard(mpMutex) );
233 const sal_Int32 nCount = aPropertyNames.getLength();
235 if( nCount != aValues.getLength() )
236 throw IllegalArgumentException();
238 if( nCount )
240 _preSetValues();
242 const Any * pAny = aValues.getConstArray();
243 const OUString * pString = aPropertyNames.getConstArray();
244 PropertyDataHash::const_iterator aEnd = mpInfo->maMap.end(), aIter;
246 //!! have an auto_ptr to an array of OGuards in order to have the
247 //!! allocated memory properly freed (exception safe!).
248 //!! Since the array itself has auto_ptrs as members we have to use a
249 //!! helper class 'AutoOGuardArray' in order to have
250 //!! the acquired locks properly released.
251 AutoOGuardArray aOGuardArray( nCount );
253 for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny )
255 aIter = mpInfo->maMap.find ( *pString );
256 if ( aIter == aEnd )
257 throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) );
259 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
260 _setSingleValue( *((*aIter).second->mpInfo), *pAny );
261 else
263 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
264 if (!pSlave->IsInit())
266 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
267 if (pSlave->mpSlave->mpMutex)
268 aOGuardArray[i].reset( new vos::OGuard(pSlave->mpSlave->mpMutex) );
270 pSlave->mpSlave->_preSetValues();
271 pSlave->SetInit ( sal_True );
273 pSlave->mpSlave->_setSingleValue( *((*aIter).second->mpInfo), *pAny );
277 _postSetValues();
278 SlaveMap::const_iterator aSlaveIter = maSlaveMap.begin(), aSlaveEnd = maSlaveMap.end();
279 while (aSlaveIter != aSlaveEnd)
281 if ( (*aSlaveIter).second->IsInit())
283 (*aSlaveIter).second->mpSlave->_postSetValues();
284 (*aSlaveIter).second->SetInit ( sal_False );
286 ++aSlaveIter;
291 Sequence< Any > SAL_CALL MasterPropertySet::getPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames )
292 throw(RuntimeException)
294 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
295 std::auto_ptr< vos::OGuard > pMutexGuard;
296 if (mpMutex)
297 pMutexGuard.reset( new vos::OGuard(mpMutex) );
299 const sal_Int32 nCount = aPropertyNames.getLength();
301 Sequence < Any > aValues ( nCount );
303 if( nCount )
305 _preGetValues();
307 Any * pAny = aValues.getArray();
308 const OUString * pString = aPropertyNames.getConstArray();
309 PropertyDataHash::const_iterator aEnd = mpInfo->maMap.end(), aIter;
311 //!! have an auto_ptr to an array of OGuards in order to have the
312 //!! allocated memory properly freed (exception safe!).
313 //!! Since the array itself has auto_ptrs as members we have to use a
314 //!! helper class 'AutoOGuardArray' in order to have
315 //!! the acquired locks properly released.
316 AutoOGuardArray aOGuardArray( nCount );
318 for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny )
320 aIter = mpInfo->maMap.find ( *pString );
321 if ( aIter == aEnd )
322 throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) );
324 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
325 _getSingleValue( *((*aIter).second->mpInfo), *pAny );
326 else
328 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
329 if (!pSlave->IsInit())
331 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
332 if (pSlave->mpSlave->mpMutex)
333 aOGuardArray[i].reset( new vos::OGuard(pSlave->mpSlave->mpMutex) );
335 pSlave->mpSlave->_preGetValues();
336 pSlave->SetInit ( sal_True );
338 pSlave->mpSlave->_getSingleValue( *((*aIter).second->mpInfo), *pAny );
342 _postSetValues();
343 SlaveMap::const_iterator aSlaveIter = maSlaveMap.begin(), aSlaveEnd = maSlaveMap.end();
344 while (aSlaveIter != aSlaveEnd)
346 if ( (*aSlaveIter).second->IsInit())
348 (*aSlaveIter).second->mpSlave->_postSetValues();
349 (*aSlaveIter).second->SetInit ( sal_False );
351 ++aSlaveIter;
354 return aValues;
357 void SAL_CALL MasterPropertySet::addPropertiesChangeListener( const Sequence< ::rtl::OUString >&, const Reference< XPropertiesChangeListener >& )
358 throw(RuntimeException)
360 // todo
363 void SAL_CALL MasterPropertySet::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& )
364 throw(RuntimeException)
366 // todo
369 void SAL_CALL MasterPropertySet::firePropertiesChangeEvent( const Sequence< ::rtl::OUString >&, const Reference< XPropertiesChangeListener >& )
370 throw(RuntimeException)
372 // todo
375 // XPropertyState
376 PropertyState SAL_CALL MasterPropertySet::getPropertyState( const ::rtl::OUString& PropertyName )
377 throw(UnknownPropertyException, RuntimeException)
379 PropertyDataHash::const_iterator aIter = mpInfo->maMap.find( PropertyName );
380 if( aIter == mpInfo->maMap.end())
381 throw UnknownPropertyException( PropertyName, static_cast< XPropertySet* >( this ) );
383 PropertyState aState;
385 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
387 _preGetPropertyState();
388 _getPropertyState( *((*aIter).second->mpInfo), aState );
389 _postGetPropertyState();
391 else
393 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mpSlave;
395 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
396 std::auto_ptr< vos::OGuard > pMutexGuard;
397 if (pSlave->mpMutex)
398 pMutexGuard.reset( new vos::OGuard(pSlave->mpMutex) );
400 pSlave->_preGetPropertyState();
401 pSlave->_getPropertyState( *((*aIter).second->mpInfo), aState );
402 pSlave->_postGetPropertyState();
405 return aState;
408 Sequence< PropertyState > SAL_CALL MasterPropertySet::getPropertyStates( const Sequence< ::rtl::OUString >& rPropertyNames )
409 throw(UnknownPropertyException, RuntimeException)
411 const sal_Int32 nCount = rPropertyNames.getLength();
413 Sequence< PropertyState > aStates( nCount );
414 if( nCount )
416 PropertyState * pState = aStates.getArray();
417 const OUString * pString = rPropertyNames.getConstArray();
418 PropertyDataHash::const_iterator aEnd = mpInfo->maMap.end(), aIter;
419 _preGetPropertyState();
421 for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pState )
423 aIter = mpInfo->maMap.find ( *pString );
424 if ( aIter == aEnd )
425 throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) );
427 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
428 _getPropertyState( *((*aIter).second->mpInfo), *pState );
429 else
431 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
432 if (!pSlave->IsInit())
434 pSlave->mpSlave->_preGetPropertyState();
435 pSlave->SetInit ( sal_True );
437 pSlave->mpSlave->_getPropertyState( *((*aIter).second->mpInfo), *pState );
440 _postGetPropertyState();
441 SlaveMap::const_iterator aSlaveIter = maSlaveMap.begin(), aSlaveEnd = maSlaveMap.end();
442 while (aSlaveIter != aSlaveEnd)
444 if ( (*aSlaveIter).second->IsInit())
446 (*aSlaveIter).second->mpSlave->_postGetPropertyState();
447 (*aSlaveIter).second->SetInit ( sal_False );
449 ++aSlaveIter;
452 return aStates;
455 void SAL_CALL MasterPropertySet::setPropertyToDefault( const ::rtl::OUString& rPropertyName )
456 throw(UnknownPropertyException, RuntimeException)
458 PropertyDataHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName );
460 if( aIter == mpInfo->maMap.end())
461 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
462 _setPropertyToDefault( *((*aIter).second->mpInfo) );
465 Any SAL_CALL MasterPropertySet::getPropertyDefault( const ::rtl::OUString& rPropertyName )
466 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
468 PropertyDataHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName );
470 if( aIter == mpInfo->maMap.end())
471 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
472 return _getPropertyDefault( *((*aIter).second->mpInfo) );
475 void MasterPropertySet::_preGetPropertyState ()
476 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException )
478 OSL_ENSURE( sal_False, "you have to implement this yourself!");
481 void MasterPropertySet::_getPropertyState( const comphelper::PropertyInfo&, PropertyState& )
482 throw(UnknownPropertyException )
484 OSL_ENSURE( sal_False, "you have to implement this yourself!");
487 void MasterPropertySet::_postGetPropertyState ()
488 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException )
490 OSL_ENSURE( sal_False, "you have to implement this yourself!");
493 void MasterPropertySet::_setPropertyToDefault( const comphelper::PropertyInfo& )
494 throw(UnknownPropertyException )
496 OSL_ENSURE( sal_False, "you have to implement this yourself!");
499 Any MasterPropertySet::_getPropertyDefault( const comphelper::PropertyInfo& )
500 throw(UnknownPropertyException, WrappedTargetException )
502 OSL_ENSURE( sal_False, "you have to implement this yourself!");
503 Any aAny;
504 return aAny;