1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MasterPropertySet.cxx,v $
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>
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 //////////////////////////////////////////////////////////////////////
49 std::auto_ptr
< vos::OGuard
> * pGuardArray
;
52 AutoOGuardArray( sal_Int32 nNumElements
);
55 std::auto_ptr
< vos::OGuard
> & operator[] ( sal_Int32 i
) { return pGuardArray
[i
]; }
58 AutoOGuardArray::AutoOGuardArray( sal_Int32 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
;
81 SlaveData::SlaveData ( ChainablePropertySet
*pSlave
)
84 , mbInit ( sal_False
)
88 MasterPropertySet::MasterPropertySet( comphelper::MasterPropertySetInfo
* pInfo
, IMutex
*pMutex
)
97 void MasterPropertySet::lockMutex()
102 void MasterPropertySet::unlockMutex()
108 MasterPropertySet::~MasterPropertySet()
111 SlaveMap::iterator aEnd
= maSlaveMap
.end(), aIter
= maSlaveMap
.begin();
112 while (aIter
!= aEnd
)
114 delete (*aIter
).second
;
120 Reference
< XPropertySetInfo
> SAL_CALL
MasterPropertySet::getPropertySetInfo( )
121 throw(RuntimeException
)
126 void MasterPropertySet::registerSlave ( ChainablePropertySet
*pNewSet
)
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
;
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 !
149 _setSingleValue( *((*aIter
).second
->mpInfo
), rValue
);
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
;
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
;
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 ) );
181 if ( (*aIter
).second
->mnMapId
== 0 ) // 0 means it's one of ours !
184 _getSingleValue( *((*aIter
).second
->mpInfo
), aAny
);
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
;
194 pMutexGuard2
.reset( new vos::OGuard(pSlave
->mpMutex
) );
196 pSlave
->_preGetValues();
197 pSlave
->_getSingleValue( *((*aIter
).second
->mpInfo
), aAny
);
198 pSlave
->_postGetValues();
203 void SAL_CALL
MasterPropertySet::addPropertyChangeListener( const ::rtl::OUString
&, const Reference
< XPropertyChangeListener
>& )
204 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
209 void SAL_CALL
MasterPropertySet::removePropertyChangeListener( const ::rtl::OUString
&, const Reference
< XPropertyChangeListener
>& )
210 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
215 void SAL_CALL
MasterPropertySet::addVetoableChangeListener( const ::rtl::OUString
&, const Reference
< XVetoableChangeListener
>& )
216 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
221 void SAL_CALL
MasterPropertySet::removeVetoableChangeListener( const ::rtl::OUString
&, const Reference
< XVetoableChangeListener
>& )
222 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
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
;
234 pMutexGuard
.reset( new vos::OGuard(mpMutex
) );
236 const sal_Int32 nCount
= aPropertyNames
.getLength();
238 if( nCount
!= aValues
.getLength() )
239 throw IllegalArgumentException();
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
);
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
);
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
);
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
);
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
;
300 pMutexGuard
.reset( new vos::OGuard(mpMutex
) );
302 const sal_Int32 nCount
= aPropertyNames
.getLength();
304 Sequence
< Any
> aValues ( nCount
);
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
);
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
);
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
);
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
);
360 void SAL_CALL
MasterPropertySet::addPropertiesChangeListener( const Sequence
< ::rtl::OUString
>&, const Reference
< XPropertiesChangeListener
>& )
361 throw(RuntimeException
)
366 void SAL_CALL
MasterPropertySet::removePropertiesChangeListener( const Reference
< XPropertiesChangeListener
>& )
367 throw(RuntimeException
)
372 void SAL_CALL
MasterPropertySet::firePropertiesChangeEvent( const Sequence
< ::rtl::OUString
>&, const Reference
< XPropertiesChangeListener
>& )
373 throw(RuntimeException
)
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();
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
;
401 pMutexGuard
.reset( new vos::OGuard(pSlave
->mpMutex
) );
403 pSlave
->_preGetPropertyState();
404 pSlave
->_getPropertyState( *((*aIter
).second
->mpInfo
), aState
);
405 pSlave
->_postGetPropertyState();
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
);
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
);
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
);
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
);
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!");