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>
33 std::vector
<std::unique_ptr
< osl::Guard
< comphelper::SolarMutex
> >> maGuardArray
;
36 explicit AutoOGuardArray( sal_Int32 nNumElements
);
38 std::unique_ptr
< osl::Guard
< comphelper::SolarMutex
> > & operator[] ( sal_Int32 i
) { return maGuardArray
[i
]; }
41 AutoOGuardArray::AutoOGuardArray( sal_Int32 nNumElements
) : maGuardArray(nNumElements
)
46 using namespace ::comphelper
;
47 using namespace ::com::sun::star
;
48 using namespace ::com::sun::star::uno
;
49 using namespace ::com::sun::star::lang
;
50 using namespace ::com::sun::star::beans
;
53 SlaveData::SlaveData ( ChainablePropertySet
*pSlave
)
59 MasterPropertySet::MasterPropertySet( comphelper::MasterPropertySetInfo
* pInfo
, comphelper::SolarMutex
* pMutex
)
67 MasterPropertySet::~MasterPropertySet()
70 for( auto& rSlave
: maSlaveMap
)
75 Reference
< XPropertySetInfo
> SAL_CALL
MasterPropertySet::getPropertySetInfo( )
80 void MasterPropertySet::registerSlave ( ChainablePropertySet
*pNewSet
)
83 maSlaveMap
[ ++mnLastId
] = new SlaveData ( pNewSet
);
84 mxInfo
->add ( pNewSet
->mxInfo
->maMap
, mnLastId
);
87 void SAL_CALL
MasterPropertySet::setPropertyValue( const OUString
& rPropertyName
, const Any
& rValue
)
89 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
90 std::unique_ptr
< osl::Guard
< comphelper::SolarMutex
> > xMutexGuard
;
92 xMutexGuard
.reset( new osl::Guard
< comphelper::SolarMutex
>(mpMutex
) );
94 PropertyDataHash::const_iterator aIter
= mxInfo
->maMap
.find ( rPropertyName
);
96 if( aIter
== mxInfo
->maMap
.end())
97 throw UnknownPropertyException( rPropertyName
, static_cast< XPropertySet
* >( this ) );
99 if ( (*aIter
).second
->mnMapId
== 0 ) // 0 means it's one of ours !
102 _setSingleValue( *((*aIter
).second
->mpInfo
), rValue
);
107 ChainablePropertySet
* pSlave
= maSlaveMap
[ (*aIter
).second
->mnMapId
]->mxSlave
.get();
109 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
110 std::unique_ptr
< osl::Guard
< comphelper::SolarMutex
> > xMutexGuard2
;
112 xMutexGuard2
.reset( new osl::Guard
< comphelper::SolarMutex
>(pSlave
->mpMutex
) );
114 pSlave
->_preSetValues();
115 pSlave
->_setSingleValue( *((*aIter
).second
->mpInfo
), rValue
);
116 pSlave
->_postSetValues();
120 Any SAL_CALL
MasterPropertySet::getPropertyValue( const OUString
& rPropertyName
)
122 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
123 std::unique_ptr
< osl::Guard
< comphelper::SolarMutex
> > xMutexGuard
;
125 xMutexGuard
.reset( new osl::Guard
< comphelper::SolarMutex
>(mpMutex
) );
127 PropertyDataHash::const_iterator aIter
= mxInfo
->maMap
.find ( rPropertyName
);
129 if( aIter
== mxInfo
->maMap
.end())
130 throw UnknownPropertyException( rPropertyName
, static_cast< XPropertySet
* >( this ) );
133 if ( (*aIter
).second
->mnMapId
== 0 ) // 0 means it's one of ours !
136 _getSingleValue( *((*aIter
).second
->mpInfo
), aAny
);
141 ChainablePropertySet
* pSlave
= maSlaveMap
[ (*aIter
).second
->mnMapId
]->mxSlave
.get();
143 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
144 std::unique_ptr
< osl::Guard
< comphelper::SolarMutex
> > xMutexGuard2
;
146 xMutexGuard2
.reset( new osl::Guard
< comphelper::SolarMutex
>(pSlave
->mpMutex
) );
148 pSlave
->_preGetValues();
149 pSlave
->_getSingleValue( *((*aIter
).second
->mpInfo
), aAny
);
150 pSlave
->_postGetValues();
155 void SAL_CALL
MasterPropertySet::addPropertyChangeListener( const OUString
&, const Reference
< XPropertyChangeListener
>& )
160 void SAL_CALL
MasterPropertySet::removePropertyChangeListener( const OUString
&, const Reference
< XPropertyChangeListener
>& )
165 void SAL_CALL
MasterPropertySet::addVetoableChangeListener( const OUString
&, const Reference
< XVetoableChangeListener
>& )
170 void SAL_CALL
MasterPropertySet::removeVetoableChangeListener( const OUString
&, const Reference
< XVetoableChangeListener
>& )
176 void SAL_CALL
MasterPropertySet::setPropertyValues( const Sequence
< OUString
>& aPropertyNames
, const Sequence
< Any
>& aValues
)
178 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
179 std::unique_ptr
< osl::Guard
< comphelper::SolarMutex
> > xMutexGuard
;
181 xMutexGuard
.reset( new osl::Guard
< comphelper::SolarMutex
>(mpMutex
) );
183 const sal_Int32 nCount
= aPropertyNames
.getLength();
185 if( nCount
!= aValues
.getLength() )
186 throw IllegalArgumentException();
192 const Any
* pAny
= aValues
.getConstArray();
193 const OUString
* pString
= aPropertyNames
.getConstArray();
194 PropertyDataHash::const_iterator aEnd
= mxInfo
->maMap
.end(), aIter
;
196 //!! have a unique_ptr to an array of OGuards in order to have the
197 //!! allocated memory properly freed (exception safe!).
198 //!! Since the array itself has unique_ptrs as members we have to use a
199 //!! helper class 'AutoOGuardArray' in order to have
200 //!! the acquired locks properly released.
201 AutoOGuardArray
aOGuardArray( nCount
);
203 for ( sal_Int32 i
= 0; i
< nCount
; ++i
, ++pString
, ++pAny
)
205 aIter
= mxInfo
->maMap
.find ( *pString
);
207 throw RuntimeException( *pString
, static_cast< XPropertySet
* >( this ) );
209 if ( (*aIter
).second
->mnMapId
== 0 ) // 0 means it's one of ours !
210 _setSingleValue( *((*aIter
).second
->mpInfo
), *pAny
);
213 SlaveData
* pSlave
= maSlaveMap
[ (*aIter
).second
->mnMapId
];
214 if (!pSlave
->IsInit())
216 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
217 if (pSlave
->mxSlave
->mpMutex
)
218 aOGuardArray
[i
].reset( new osl::Guard
< comphelper::SolarMutex
>(pSlave
->mxSlave
->mpMutex
) );
220 pSlave
->mxSlave
->_preSetValues();
221 pSlave
->SetInit ( true );
223 pSlave
->mxSlave
->_setSingleValue( *((*aIter
).second
->mpInfo
), *pAny
);
228 for( const auto& rSlave
: maSlaveMap
)
230 if( rSlave
.second
->IsInit() )
232 rSlave
.second
->mxSlave
->_postSetValues();
233 rSlave
.second
->SetInit( false );
239 Sequence
< Any
> SAL_CALL
MasterPropertySet::getPropertyValues( const Sequence
< OUString
>& aPropertyNames
)
241 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
242 std::unique_ptr
< osl::Guard
< comphelper::SolarMutex
> > xMutexGuard
;
244 xMutexGuard
.reset( new osl::Guard
< comphelper::SolarMutex
>(mpMutex
) );
246 const sal_Int32 nCount
= aPropertyNames
.getLength();
248 Sequence
< Any
> aValues ( nCount
);
254 Any
* pAny
= aValues
.getArray();
255 const OUString
* pString
= aPropertyNames
.getConstArray();
256 PropertyDataHash::const_iterator aEnd
= mxInfo
->maMap
.end(), aIter
;
258 //!! have a unique_ptr to an array of OGuards in order to have the
259 //!! allocated memory properly freed (exception safe!).
260 //!! Since the array itself has unique_ptrs as members we have to use a
261 //!! helper class 'AutoOGuardArray' in order to have
262 //!! the acquired locks properly released.
263 AutoOGuardArray
aOGuardArray( nCount
);
265 for ( sal_Int32 i
= 0; i
< nCount
; ++i
, ++pString
, ++pAny
)
267 aIter
= mxInfo
->maMap
.find ( *pString
);
269 throw RuntimeException( *pString
, static_cast< XPropertySet
* >( this ) );
271 if ( (*aIter
).second
->mnMapId
== 0 ) // 0 means it's one of ours !
272 _getSingleValue( *((*aIter
).second
->mpInfo
), *pAny
);
275 SlaveData
* pSlave
= maSlaveMap
[ (*aIter
).second
->mnMapId
];
276 if (!pSlave
->IsInit())
278 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
279 if (pSlave
->mxSlave
->mpMutex
)
280 aOGuardArray
[i
].reset( new osl::Guard
< comphelper::SolarMutex
>(pSlave
->mxSlave
->mpMutex
) );
282 pSlave
->mxSlave
->_preGetValues();
283 pSlave
->SetInit ( true );
285 pSlave
->mxSlave
->_getSingleValue( *((*aIter
).second
->mpInfo
), *pAny
);
290 for( const auto& rSlave
: maSlaveMap
)
292 if( rSlave
.second
->IsInit() )
294 rSlave
.second
->mxSlave
->_postSetValues();
295 rSlave
.second
->SetInit( false );
302 void SAL_CALL
MasterPropertySet::addPropertiesChangeListener( const Sequence
< OUString
>&, const Reference
< XPropertiesChangeListener
>& )
307 void SAL_CALL
MasterPropertySet::removePropertiesChangeListener( const Reference
< XPropertiesChangeListener
>& )
312 void SAL_CALL
MasterPropertySet::firePropertiesChangeEvent( const Sequence
< OUString
>&, const Reference
< XPropertiesChangeListener
>& )
318 PropertyState SAL_CALL
MasterPropertySet::getPropertyState( const OUString
& PropertyName
)
320 PropertyDataHash::const_iterator aIter
= mxInfo
->maMap
.find( PropertyName
);
321 if( aIter
== mxInfo
->maMap
.end())
322 throw UnknownPropertyException( PropertyName
, static_cast< XPropertySet
* >( this ) );
324 // 0 means it's one of ours !
325 if ( (*aIter
).second
->mnMapId
!= 0 )
327 ChainablePropertySet
* pSlave
= maSlaveMap
[ (*aIter
).second
->mnMapId
]->mxSlave
.get();
329 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
330 std::unique_ptr
< osl::Guard
< comphelper::SolarMutex
> > xMutexGuard
;
332 xMutexGuard
.reset( new osl::Guard
< comphelper::SolarMutex
>(pSlave
->mpMutex
) );
335 return PropertyState_AMBIGUOUS_VALUE
;
338 Sequence
< PropertyState
> SAL_CALL
MasterPropertySet::getPropertyStates( const Sequence
< OUString
>& rPropertyNames
)
340 const sal_Int32 nCount
= rPropertyNames
.getLength();
342 Sequence
< PropertyState
> aStates( nCount
);
345 PropertyState
* pState
= aStates
.getArray();
346 const OUString
* pString
= rPropertyNames
.getConstArray();
347 PropertyDataHash::const_iterator aEnd
= mxInfo
->maMap
.end(), aIter
;
349 for ( sal_Int32 i
= 0; i
< nCount
; ++i
, ++pString
, ++pState
)
351 aIter
= mxInfo
->maMap
.find ( *pString
);
353 throw UnknownPropertyException( *pString
, static_cast< XPropertySet
* >( this ) );
355 // 0 means it's one of ours !
356 if ( (*aIter
).second
->mnMapId
!= 0 )
358 SlaveData
* pSlave
= maSlaveMap
[ (*aIter
).second
->mnMapId
];
359 if (!pSlave
->IsInit())
361 pSlave
->SetInit ( true );
365 for( const auto& rSlave
: maSlaveMap
)
367 if( rSlave
.second
->IsInit() )
369 rSlave
.second
->SetInit( false );
376 void SAL_CALL
MasterPropertySet::setPropertyToDefault( const OUString
& rPropertyName
)
378 PropertyDataHash::const_iterator aIter
= mxInfo
->maMap
.find ( rPropertyName
);
380 if( aIter
== mxInfo
->maMap
.end())
381 throw UnknownPropertyException( rPropertyName
, static_cast< XPropertySet
* >( this ) );
384 Any SAL_CALL
MasterPropertySet::getPropertyDefault( const OUString
& rPropertyName
)
386 PropertyDataHash::const_iterator aIter
= mxInfo
->maMap
.find ( rPropertyName
);
388 if( aIter
== mxInfo
->maMap
.end())
389 throw UnknownPropertyException( rPropertyName
, static_cast< XPropertySet
* >( this ) );
393 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */