1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
36 std::vector
<std::optional
< osl::Guard
< comphelper::SolarMutex
> >> maGuardArray
;
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
)
64 MasterPropertySet::MasterPropertySet( comphelper::MasterPropertySetInfo
* pInfo
, comphelper::SolarMutex
* pMutex
)
72 MasterPropertySet::~MasterPropertySet()
75 for( const auto& rSlave
: maSlaveMap
)
80 Reference
< XPropertySetInfo
> SAL_CALL
MasterPropertySet::getPropertySetInfo( )
85 void MasterPropertySet::registerSlave ( ChainablePropertySet
*pNewSet
)
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
;
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 !
107 _setSingleValue( *((*aIter
).second
->mpInfo
), rValue
);
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
;
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
;
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 ) );
138 if ( (*aIter
).second
->mnMapId
== 0 ) // 0 means it's one of ours !
141 _getSingleValue( *((*aIter
).second
->mpInfo
), aAny
);
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
;
151 xMutexGuard2
.emplace( pSlave
->mpMutex
);
153 pSlave
->_preGetValues();
154 pSlave
->_getSingleValue( *((*aIter
).second
->mpInfo
), aAny
);
155 pSlave
->_postGetValues();
160 void SAL_CALL
MasterPropertySet::addPropertyChangeListener( const OUString
&, const Reference
< XPropertyChangeListener
>& )
165 void SAL_CALL
MasterPropertySet::removePropertyChangeListener( const OUString
&, const Reference
< XPropertyChangeListener
>& )
170 void SAL_CALL
MasterPropertySet::addVetoableChangeListener( const OUString
&, const Reference
< XVetoableChangeListener
>& )
175 void SAL_CALL
MasterPropertySet::removeVetoableChangeListener( const OUString
&, const Reference
< XVetoableChangeListener
>& )
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
;
186 xMutexGuard
.emplace( mpMutex
);
188 const sal_Int32 nCount
= aPropertyNames
.getLength();
190 if( nCount
!= aValues
.getLength() )
191 throw IllegalArgumentException();
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
]);
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
]);
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
]);
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
;
247 xMutexGuard
.emplace( mpMutex
);
249 const sal_Int32 nCount
= aPropertyNames
.getLength();
251 Sequence
< Any
> aValues ( nCount
);
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
]);
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
]);
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
]);
292 for( const auto& rSlave
: maSlaveMap
)
294 if( rSlave
.second
->IsInit() )
296 rSlave
.second
->mxSlave
->_postSetValues();
297 rSlave
.second
->SetInit( false );
304 void SAL_CALL
MasterPropertySet::addPropertiesChangeListener( const Sequence
< OUString
>&, const Reference
< XPropertiesChangeListener
>& )
309 void SAL_CALL
MasterPropertySet::removePropertiesChangeListener( const Reference
< XPropertiesChangeListener
>& )
314 void SAL_CALL
MasterPropertySet::firePropertiesChangeEvent( const Sequence
< OUString
>&, const Reference
< XPropertiesChangeListener
>& )
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
;
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
);
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
]);
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 );
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 ) );
396 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */