Update ooo320-m1
[ooovba.git] / comphelper / source / property / MasterPropertySet.cxx
blob438629a5f092c761c4c27007066f89dfaaf02fba
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MasterPropertySet.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_comphelper.hxx"
34 #ifndef _COMPHELPER_MASTERPROPERTYSET_HXX_
35 #include <comphelper/MasterPropertySet.hxx>
36 #endif
37 #include <comphelper/MasterPropertySetInfo.hxx>
38 #include <comphelper/ChainablePropertySet.hxx>
39 #include <comphelper/ChainablePropertySetInfo.hxx>
40 #include <vos/mutex.hxx>
42 #include <memory> // STL auto_ptr
44 //////////////////////////////////////////////////////////////////////
46 class AutoOGuardArray
48 sal_Int32 nSize;
49 std::auto_ptr< vos::OGuard > * pGuardArray;
51 public:
52 AutoOGuardArray( sal_Int32 nNumElements );
53 ~AutoOGuardArray();
55 std::auto_ptr< vos::OGuard > & operator[] ( sal_Int32 i ) { return pGuardArray[i]; }
58 AutoOGuardArray::AutoOGuardArray( sal_Int32 nNumElements )
60 nSize = nNumElements;
61 pGuardArray = new std::auto_ptr< vos::OGuard >[ nSize ];
64 AutoOGuardArray::~AutoOGuardArray()
66 //!! release auto_ptr's and thus the mutexes locks
67 delete [] pGuardArray;
71 //////////////////////////////////////////////////////////////////////
73 using namespace ::rtl;
74 using namespace ::comphelper;
75 using namespace ::com::sun::star;
76 using namespace ::com::sun::star::uno;
77 using namespace ::com::sun::star::lang;
78 using namespace ::com::sun::star::beans;
79 using vos::IMutex;
81 SlaveData::SlaveData ( ChainablePropertySet *pSlave)
82 : mpSlave ( pSlave )
83 , mxSlave ( pSlave )
84 , mbInit ( sal_False )
88 MasterPropertySet::MasterPropertySet( comphelper::MasterPropertySetInfo* pInfo, IMutex *pMutex )
89 throw()
90 : mpInfo ( pInfo )
91 , mpMutex ( pMutex )
92 , mnLastId ( 0 )
93 , mxInfo ( pInfo )
97 void MasterPropertySet::lockMutex()
99 if (mpMutex)
100 mpMutex->acquire();
102 void MasterPropertySet::unlockMutex()
104 if (mpMutex)
105 mpMutex->release();
108 MasterPropertySet::~MasterPropertySet()
109 throw()
111 SlaveMap::iterator aEnd = maSlaveMap.end(), aIter = maSlaveMap.begin();
112 while (aIter != aEnd )
114 delete (*aIter).second;
115 aIter++;
119 // XPropertySet
120 Reference< XPropertySetInfo > SAL_CALL MasterPropertySet::getPropertySetInfo( )
121 throw(RuntimeException)
123 return mxInfo;
126 void MasterPropertySet::registerSlave ( ChainablePropertySet *pNewSet )
127 throw()
129 maSlaveMap [ ++mnLastId ] = new SlaveData ( pNewSet );
130 mpInfo->add ( pNewSet->mpInfo->maMap, mnLastId );
133 void SAL_CALL MasterPropertySet::setPropertyValue( const ::rtl::OUString& rPropertyName, const Any& rValue )
134 throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
136 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
137 std::auto_ptr< vos::OGuard > pMutexGuard;
138 if (mpMutex)
139 pMutexGuard.reset( new vos::OGuard(mpMutex) );
141 PropertyDataHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName );
143 if( aIter == mpInfo->maMap.end())
144 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
146 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
148 _preSetValues();
149 _setSingleValue( *((*aIter).second->mpInfo), rValue );
150 _postSetValues();
152 else
154 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mpSlave;
156 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
157 std::auto_ptr< vos::OGuard > pMutexGuard2;
158 if (pSlave->mpMutex)
159 pMutexGuard2.reset( new vos::OGuard(pSlave->mpMutex) );
161 pSlave->_preSetValues();
162 pSlave->_setSingleValue( *((*aIter).second->mpInfo), rValue );
163 pSlave->_postSetValues();
167 Any SAL_CALL MasterPropertySet::getPropertyValue( const ::rtl::OUString& rPropertyName )
168 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
170 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
171 std::auto_ptr< vos::OGuard > pMutexGuard;
172 if (mpMutex)
173 pMutexGuard.reset( new vos::OGuard(mpMutex) );
175 PropertyDataHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName );
177 if( aIter == mpInfo->maMap.end())
178 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
180 Any aAny;
181 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
183 _preGetValues();
184 _getSingleValue( *((*aIter).second->mpInfo), aAny );
185 _postGetValues();
187 else
189 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mpSlave;
191 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
192 std::auto_ptr< vos::OGuard > pMutexGuard2;
193 if (pSlave->mpMutex)
194 pMutexGuard2.reset( new vos::OGuard(pSlave->mpMutex) );
196 pSlave->_preGetValues();
197 pSlave->_getSingleValue( *((*aIter).second->mpInfo), aAny );
198 pSlave->_postGetValues();
200 return aAny;
203 void SAL_CALL MasterPropertySet::addPropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& )
204 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
206 // todo
209 void SAL_CALL MasterPropertySet::removePropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& )
210 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
212 // todo
215 void SAL_CALL MasterPropertySet::addVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& )
216 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
218 // todo
221 void SAL_CALL MasterPropertySet::removeVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& )
222 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
224 // todo
227 // XMultiPropertySet
228 void SAL_CALL MasterPropertySet::setPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames, const Sequence< Any >& aValues )
229 throw(PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
231 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
232 std::auto_ptr< vos::OGuard > pMutexGuard;
233 if (mpMutex)
234 pMutexGuard.reset( new vos::OGuard(mpMutex) );
236 const sal_Int32 nCount = aPropertyNames.getLength();
238 if( nCount != aValues.getLength() )
239 throw IllegalArgumentException();
241 if( nCount )
243 _preSetValues();
245 const Any * pAny = aValues.getConstArray();
246 const OUString * pString = aPropertyNames.getConstArray();
247 PropertyDataHash::const_iterator aEnd = mpInfo->maMap.end(), aIter;
249 //!! have an auto_ptr to an array of OGuards in order to have the
250 //!! allocated memory properly freed (exception safe!).
251 //!! Since the array itself has auto_ptrs as members we have to use a
252 //!! helper class 'AutoOGuardArray' in order to have
253 //!! the acquired locks properly released.
254 AutoOGuardArray aOGuardArray( nCount );
256 for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny )
258 aIter = mpInfo->maMap.find ( *pString );
259 if ( aIter == aEnd )
260 throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) );
262 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
263 _setSingleValue( *((*aIter).second->mpInfo), *pAny );
264 else
266 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
267 if (!pSlave->IsInit())
269 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
270 if (pSlave->mpSlave->mpMutex)
271 aOGuardArray[i].reset( new vos::OGuard(pSlave->mpSlave->mpMutex) );
273 pSlave->mpSlave->_preSetValues();
274 pSlave->SetInit ( sal_True );
276 pSlave->mpSlave->_setSingleValue( *((*aIter).second->mpInfo), *pAny );
280 _postSetValues();
281 SlaveMap::const_iterator aSlaveIter = maSlaveMap.begin(), aSlaveEnd = maSlaveMap.end();
282 while (aSlaveIter != aSlaveEnd)
284 if ( (*aSlaveIter).second->IsInit())
286 (*aSlaveIter).second->mpSlave->_postSetValues();
287 (*aSlaveIter).second->SetInit ( sal_False );
289 ++aSlaveIter;
294 Sequence< Any > SAL_CALL MasterPropertySet::getPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames )
295 throw(RuntimeException)
297 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
298 std::auto_ptr< vos::OGuard > pMutexGuard;
299 if (mpMutex)
300 pMutexGuard.reset( new vos::OGuard(mpMutex) );
302 const sal_Int32 nCount = aPropertyNames.getLength();
304 Sequence < Any > aValues ( nCount );
306 if( nCount )
308 _preGetValues();
310 Any * pAny = aValues.getArray();
311 const OUString * pString = aPropertyNames.getConstArray();
312 PropertyDataHash::const_iterator aEnd = mpInfo->maMap.end(), aIter;
314 //!! have an auto_ptr to an array of OGuards in order to have the
315 //!! allocated memory properly freed (exception safe!).
316 //!! Since the array itself has auto_ptrs as members we have to use a
317 //!! helper class 'AutoOGuardArray' in order to have
318 //!! the acquired locks properly released.
319 AutoOGuardArray aOGuardArray( nCount );
321 for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny )
323 aIter = mpInfo->maMap.find ( *pString );
324 if ( aIter == aEnd )
325 throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) );
327 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
328 _getSingleValue( *((*aIter).second->mpInfo), *pAny );
329 else
331 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
332 if (!pSlave->IsInit())
334 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
335 if (pSlave->mpSlave->mpMutex)
336 aOGuardArray[i].reset( new vos::OGuard(pSlave->mpSlave->mpMutex) );
338 pSlave->mpSlave->_preGetValues();
339 pSlave->SetInit ( sal_True );
341 pSlave->mpSlave->_getSingleValue( *((*aIter).second->mpInfo), *pAny );
345 _postSetValues();
346 SlaveMap::const_iterator aSlaveIter = maSlaveMap.begin(), aSlaveEnd = maSlaveMap.end();
347 while (aSlaveIter != aSlaveEnd)
349 if ( (*aSlaveIter).second->IsInit())
351 (*aSlaveIter).second->mpSlave->_postSetValues();
352 (*aSlaveIter).second->SetInit ( sal_False );
354 ++aSlaveIter;
357 return aValues;
360 void SAL_CALL MasterPropertySet::addPropertiesChangeListener( const Sequence< ::rtl::OUString >&, const Reference< XPropertiesChangeListener >& )
361 throw(RuntimeException)
363 // todo
366 void SAL_CALL MasterPropertySet::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& )
367 throw(RuntimeException)
369 // todo
372 void SAL_CALL MasterPropertySet::firePropertiesChangeEvent( const Sequence< ::rtl::OUString >&, const Reference< XPropertiesChangeListener >& )
373 throw(RuntimeException)
375 // todo
378 // XPropertyState
379 PropertyState SAL_CALL MasterPropertySet::getPropertyState( const ::rtl::OUString& PropertyName )
380 throw(UnknownPropertyException, RuntimeException)
382 PropertyDataHash::const_iterator aIter = mpInfo->maMap.find( PropertyName );
383 if( aIter == mpInfo->maMap.end())
384 throw UnknownPropertyException( PropertyName, static_cast< XPropertySet* >( this ) );
386 PropertyState aState;
388 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
390 _preGetPropertyState();
391 _getPropertyState( *((*aIter).second->mpInfo), aState );
392 _postGetPropertyState();
394 else
396 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mpSlave;
398 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
399 std::auto_ptr< vos::OGuard > pMutexGuard;
400 if (pSlave->mpMutex)
401 pMutexGuard.reset( new vos::OGuard(pSlave->mpMutex) );
403 pSlave->_preGetPropertyState();
404 pSlave->_getPropertyState( *((*aIter).second->mpInfo), aState );
405 pSlave->_postGetPropertyState();
408 return aState;
411 Sequence< PropertyState > SAL_CALL MasterPropertySet::getPropertyStates( const Sequence< ::rtl::OUString >& rPropertyNames )
412 throw(UnknownPropertyException, RuntimeException)
414 const sal_Int32 nCount = rPropertyNames.getLength();
416 Sequence< PropertyState > aStates( nCount );
417 if( nCount )
419 PropertyState * pState = aStates.getArray();
420 const OUString * pString = rPropertyNames.getConstArray();
421 PropertyDataHash::const_iterator aEnd = mpInfo->maMap.end(), aIter;
422 _preGetPropertyState();
424 for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pState )
426 aIter = mpInfo->maMap.find ( *pString );
427 if ( aIter == aEnd )
428 throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) );
430 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
431 _getPropertyState( *((*aIter).second->mpInfo), *pState );
432 else
434 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
435 if (!pSlave->IsInit())
437 pSlave->mpSlave->_preGetPropertyState();
438 pSlave->SetInit ( sal_True );
440 pSlave->mpSlave->_getPropertyState( *((*aIter).second->mpInfo), *pState );
443 _postGetPropertyState();
444 SlaveMap::const_iterator aSlaveIter = maSlaveMap.begin(), aSlaveEnd = maSlaveMap.end();
445 while (aSlaveIter != aSlaveEnd)
447 if ( (*aSlaveIter).second->IsInit())
449 (*aSlaveIter).second->mpSlave->_postGetPropertyState();
450 (*aSlaveIter).second->SetInit ( sal_False );
452 ++aSlaveIter;
455 return aStates;
458 void SAL_CALL MasterPropertySet::setPropertyToDefault( const ::rtl::OUString& rPropertyName )
459 throw(UnknownPropertyException, RuntimeException)
461 PropertyDataHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName );
463 if( aIter == mpInfo->maMap.end())
464 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
465 _setPropertyToDefault( *((*aIter).second->mpInfo) );
468 Any SAL_CALL MasterPropertySet::getPropertyDefault( const ::rtl::OUString& rPropertyName )
469 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
471 PropertyDataHash::const_iterator aIter = mpInfo->maMap.find ( rPropertyName );
473 if( aIter == mpInfo->maMap.end())
474 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
475 return _getPropertyDefault( *((*aIter).second->mpInfo) );
478 void MasterPropertySet::_preGetPropertyState ()
479 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException )
481 OSL_ENSURE( sal_False, "you have to implement this yourself!");
484 void MasterPropertySet::_getPropertyState( const comphelper::PropertyInfo&, PropertyState& )
485 throw(UnknownPropertyException )
487 OSL_ENSURE( sal_False, "you have to implement this yourself!");
490 void MasterPropertySet::_postGetPropertyState ()
491 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException )
493 OSL_ENSURE( sal_False, "you have to implement this yourself!");
496 void MasterPropertySet::_setPropertyToDefault( const comphelper::PropertyInfo& )
497 throw(UnknownPropertyException )
499 OSL_ENSURE( sal_False, "you have to implement this yourself!");
502 Any MasterPropertySet::_getPropertyDefault( const comphelper::PropertyInfo& )
503 throw(UnknownPropertyException, WrappedTargetException )
505 OSL_ENSURE( sal_False, "you have to implement this yourself!");
506 Any aAny;
507 return aAny;