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>
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 //////////////////////////////////////////////////////////////////////
46 std::auto_ptr
< vos::OGuard
> * pGuardArray
;
49 AutoOGuardArray( sal_Int32 nNumElements
);
52 std::auto_ptr
< vos::OGuard
> & operator[] ( sal_Int32 i
) { return pGuardArray
[i
]; }
55 AutoOGuardArray::AutoOGuardArray( sal_Int32 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
;
78 SlaveData::SlaveData ( ChainablePropertySet
*pSlave
)
81 , mbInit ( sal_False
)
85 MasterPropertySet::MasterPropertySet( comphelper::MasterPropertySetInfo
* pInfo
, IMutex
*pMutex
)
94 void MasterPropertySet::lockMutex()
99 void MasterPropertySet::unlockMutex()
105 MasterPropertySet::~MasterPropertySet()
108 SlaveMap::iterator aEnd
= maSlaveMap
.end(), aIter
= maSlaveMap
.begin();
109 while (aIter
!= aEnd
)
111 delete (*aIter
).second
;
117 Reference
< XPropertySetInfo
> SAL_CALL
MasterPropertySet::getPropertySetInfo( )
118 throw(RuntimeException
)
123 void MasterPropertySet::registerSlave ( ChainablePropertySet
*pNewSet
)
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
;
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 !
146 _setSingleValue( *((*aIter
).second
->mpInfo
), rValue
);
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
;
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
;
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 ) );
178 if ( (*aIter
).second
->mnMapId
== 0 ) // 0 means it's one of ours !
181 _getSingleValue( *((*aIter
).second
->mpInfo
), aAny
);
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
;
191 pMutexGuard2
.reset( new vos::OGuard(pSlave
->mpMutex
) );
193 pSlave
->_preGetValues();
194 pSlave
->_getSingleValue( *((*aIter
).second
->mpInfo
), aAny
);
195 pSlave
->_postGetValues();
200 void SAL_CALL
MasterPropertySet::addPropertyChangeListener( const ::rtl::OUString
&, const Reference
< XPropertyChangeListener
>& )
201 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
206 void SAL_CALL
MasterPropertySet::removePropertyChangeListener( const ::rtl::OUString
&, const Reference
< XPropertyChangeListener
>& )
207 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
212 void SAL_CALL
MasterPropertySet::addVetoableChangeListener( const ::rtl::OUString
&, const Reference
< XVetoableChangeListener
>& )
213 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
218 void SAL_CALL
MasterPropertySet::removeVetoableChangeListener( const ::rtl::OUString
&, const Reference
< XVetoableChangeListener
>& )
219 throw(UnknownPropertyException
, WrappedTargetException
, RuntimeException
)
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
;
231 pMutexGuard
.reset( new vos::OGuard(mpMutex
) );
233 const sal_Int32 nCount
= aPropertyNames
.getLength();
235 if( nCount
!= aValues
.getLength() )
236 throw IllegalArgumentException();
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
);
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
);
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
);
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
);
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
;
297 pMutexGuard
.reset( new vos::OGuard(mpMutex
) );
299 const sal_Int32 nCount
= aPropertyNames
.getLength();
301 Sequence
< Any
> aValues ( nCount
);
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
);
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
);
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
);
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
);
357 void SAL_CALL
MasterPropertySet::addPropertiesChangeListener( const Sequence
< ::rtl::OUString
>&, const Reference
< XPropertiesChangeListener
>& )
358 throw(RuntimeException
)
363 void SAL_CALL
MasterPropertySet::removePropertiesChangeListener( const Reference
< XPropertiesChangeListener
>& )
364 throw(RuntimeException
)
369 void SAL_CALL
MasterPropertySet::firePropertiesChangeEvent( const Sequence
< ::rtl::OUString
>&, const Reference
< XPropertiesChangeListener
>& )
370 throw(RuntimeException
)
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();
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
;
398 pMutexGuard
.reset( new vos::OGuard(pSlave
->mpMutex
) );
400 pSlave
->_preGetPropertyState();
401 pSlave
->_getPropertyState( *((*aIter
).second
->mpInfo
), aState
);
402 pSlave
->_postGetPropertyState();
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
);
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
);
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
);
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
);
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!");