/src/libreoffice/chart2/source/tools/WrappedPropertySet.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
20 | | #include <WrappedPropertySet.hxx> |
21 | | #include <cppuhelper/propshlp.hxx> |
22 | | |
23 | | #include <comphelper/diagnose_ex.hxx> |
24 | | #include <sal/log.hxx> |
25 | | |
26 | | namespace chart |
27 | | { |
28 | | |
29 | | using namespace ::com::sun::star; |
30 | | using ::com::sun::star::uno::Reference; |
31 | | using ::com::sun::star::uno::Sequence; |
32 | | using ::com::sun::star::uno::Any; |
33 | | |
34 | | WrappedPropertySet::WrappedPropertySet() |
35 | 0 | { |
36 | 0 | } |
37 | | WrappedPropertySet::~WrappedPropertySet() |
38 | 0 | { |
39 | 0 | clearWrappedPropertySet(); |
40 | 0 | } |
41 | | |
42 | | Reference< beans::XPropertyState > WrappedPropertySet::getInnerPropertyState() |
43 | 0 | { |
44 | 0 | return Reference< beans::XPropertyState >( getInnerPropertySet(), uno::UNO_QUERY ); |
45 | 0 | } |
46 | | |
47 | | void WrappedPropertySet::clearWrappedPropertySet() |
48 | 0 | { |
49 | 0 | ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );//do not use different mutex than is already used for static property sequence |
50 | |
|
51 | 0 | m_pPropertyArrayHelper.reset(); |
52 | 0 | m_pWrappedPropertyMap.reset(); |
53 | |
|
54 | 0 | m_xInfo = nullptr; |
55 | 0 | } |
56 | | |
57 | | //XPropertySet |
58 | | Reference< beans::XPropertySetInfo > SAL_CALL WrappedPropertySet::getPropertySetInfo( ) |
59 | 0 | { |
60 | 0 | Reference< beans::XPropertySetInfo > xInfo = m_xInfo; |
61 | 0 | if( !xInfo.is() ) |
62 | 0 | { |
63 | 0 | ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );//do not use different mutex than is already used for static property sequence |
64 | 0 | xInfo = m_xInfo; |
65 | 0 | if( !xInfo.is() ) |
66 | 0 | { |
67 | 0 | xInfo = ::cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() ); |
68 | 0 | OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); |
69 | 0 | m_xInfo = std::move(xInfo); |
70 | 0 | } |
71 | 0 | } |
72 | 0 | else |
73 | 0 | { |
74 | 0 | OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); |
75 | 0 | } |
76 | 0 | return m_xInfo; |
77 | 0 | } |
78 | | |
79 | | void SAL_CALL WrappedPropertySet::setPropertyValue( const OUString& rPropertyName, const Any& rValue ) |
80 | 0 | { |
81 | 0 | try |
82 | 0 | { |
83 | 0 | sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName ); |
84 | 0 | const WrappedProperty* pWrappedProperty = getWrappedProperty( nHandle ); |
85 | 0 | Reference< beans::XPropertySet > xInnerPropertySet( getInnerPropertySet() ); |
86 | 0 | if( pWrappedProperty ) |
87 | 0 | pWrappedProperty->setPropertyValue( rValue, xInnerPropertySet ); |
88 | 0 | else if( xInnerPropertySet.is() ) |
89 | 0 | xInnerPropertySet->setPropertyValue( rPropertyName, rValue ); |
90 | 0 | else |
91 | 0 | { |
92 | 0 | SAL_WARN("chart2.tools", "found no inner property set to map to"); |
93 | 0 | } |
94 | 0 | } |
95 | 0 | catch( const beans::UnknownPropertyException& ) |
96 | 0 | { |
97 | 0 | throw; |
98 | 0 | } |
99 | 0 | catch( const beans::PropertyVetoException& ) |
100 | 0 | { |
101 | 0 | throw; |
102 | 0 | } |
103 | 0 | catch( const lang::IllegalArgumentException& ) |
104 | 0 | { |
105 | 0 | throw; |
106 | 0 | } |
107 | 0 | catch( const lang::WrappedTargetException& ) |
108 | 0 | { |
109 | 0 | throw; |
110 | 0 | } |
111 | 0 | catch( const uno::RuntimeException& ) |
112 | 0 | { |
113 | 0 | throw; |
114 | 0 | } |
115 | 0 | catch( const uno::Exception& ex ) |
116 | 0 | { |
117 | 0 | css::uno::Any anyEx = cppu::getCaughtException(); |
118 | 0 | TOOLS_WARN_EXCEPTION( "chart2", "invalid exception caught in WrappedPropertySet::setPropertyValue"); |
119 | 0 | throw lang::WrappedTargetException( ex.Message, nullptr, anyEx ); |
120 | 0 | } |
121 | 0 | } |
122 | | Any SAL_CALL WrappedPropertySet::getPropertyValue( const OUString& rPropertyName ) |
123 | 0 | { |
124 | 0 | Any aRet; |
125 | |
|
126 | 0 | try |
127 | 0 | { |
128 | 0 | sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName ); |
129 | 0 | const WrappedProperty* pWrappedProperty = getWrappedProperty( nHandle ); |
130 | 0 | Reference< beans::XPropertySet > xInnerPropertySet( getInnerPropertySet() ); |
131 | 0 | if( pWrappedProperty ) |
132 | 0 | aRet = pWrappedProperty->getPropertyValue( xInnerPropertySet ); |
133 | 0 | else if( xInnerPropertySet.is() ) |
134 | 0 | aRet = xInnerPropertySet->getPropertyValue( rPropertyName ); |
135 | 0 | else |
136 | 0 | { |
137 | 0 | SAL_WARN("chart2.tools", "found no inner property set to map to"); |
138 | 0 | } |
139 | 0 | } |
140 | 0 | catch( const beans::UnknownPropertyException& ) |
141 | 0 | { |
142 | 0 | throw; |
143 | 0 | } |
144 | 0 | catch( const lang::WrappedTargetException& ) |
145 | 0 | { |
146 | 0 | throw; |
147 | 0 | } |
148 | 0 | catch( const uno::RuntimeException& ) |
149 | 0 | { |
150 | 0 | throw; |
151 | 0 | } |
152 | 0 | catch( const uno::Exception& ex ) |
153 | 0 | { |
154 | 0 | css::uno::Any anyEx = cppu::getCaughtException(); |
155 | 0 | TOOLS_WARN_EXCEPTION( "chart2", "invalid exception caught in WrappedPropertySet::setPropertyValue"); |
156 | 0 | throw lang::WrappedTargetException( ex.Message, nullptr, anyEx ); |
157 | 0 | } |
158 | | |
159 | 0 | return aRet; |
160 | 0 | } |
161 | | |
162 | | void SAL_CALL WrappedPropertySet::addPropertyChangeListener( const OUString& rPropertyName, const Reference< beans::XPropertyChangeListener >& xListener ) |
163 | 0 | { |
164 | 0 | Reference< beans::XPropertySet > xInnerPropertySet( getInnerPropertySet() ); |
165 | 0 | if( xInnerPropertySet.is() ) |
166 | 0 | { |
167 | 0 | const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName ); |
168 | 0 | if( pWrappedProperty ) |
169 | 0 | xInnerPropertySet->addPropertyChangeListener( pWrappedProperty->getInnerName(), xListener ); |
170 | 0 | else |
171 | 0 | xInnerPropertySet->addPropertyChangeListener( rPropertyName, xListener ); |
172 | 0 | } |
173 | 0 | } |
174 | | void SAL_CALL WrappedPropertySet::removePropertyChangeListener( const OUString& rPropertyName, const Reference< beans::XPropertyChangeListener >& aListener ) |
175 | 0 | { |
176 | 0 | Reference< beans::XPropertySet > xInnerPropertySet( getInnerPropertySet() ); |
177 | 0 | if( xInnerPropertySet.is() ) |
178 | 0 | { |
179 | 0 | const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName ); |
180 | 0 | if( pWrappedProperty ) |
181 | 0 | xInnerPropertySet->removePropertyChangeListener( pWrappedProperty->getInnerName(), aListener ); |
182 | 0 | else |
183 | 0 | xInnerPropertySet->removePropertyChangeListener( rPropertyName, aListener ); |
184 | 0 | } |
185 | 0 | } |
186 | | void SAL_CALL WrappedPropertySet::addVetoableChangeListener( const OUString& rPropertyName, const Reference< beans::XVetoableChangeListener >& aListener ) |
187 | 0 | { |
188 | 0 | Reference< beans::XPropertySet > xInnerPropertySet( getInnerPropertySet() ); |
189 | 0 | if( xInnerPropertySet.is() ) |
190 | 0 | { |
191 | 0 | const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName ); |
192 | 0 | if( pWrappedProperty ) |
193 | 0 | xInnerPropertySet->addVetoableChangeListener( pWrappedProperty->getInnerName(), aListener ); |
194 | 0 | else |
195 | 0 | xInnerPropertySet->addVetoableChangeListener( rPropertyName, aListener ); |
196 | 0 | } |
197 | 0 | } |
198 | | void SAL_CALL WrappedPropertySet::removeVetoableChangeListener( const OUString& rPropertyName, const Reference< beans::XVetoableChangeListener >& aListener ) |
199 | 0 | { |
200 | 0 | Reference< beans::XPropertySet > xInnerPropertySet( getInnerPropertySet() ); |
201 | 0 | if( xInnerPropertySet.is() ) |
202 | 0 | { |
203 | 0 | const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName ); |
204 | 0 | if( pWrappedProperty ) |
205 | 0 | xInnerPropertySet->removeVetoableChangeListener( pWrappedProperty->getInnerName(), aListener ); |
206 | 0 | else |
207 | 0 | xInnerPropertySet->removeVetoableChangeListener( rPropertyName, aListener ); |
208 | 0 | } |
209 | 0 | } |
210 | | |
211 | | //XMultiPropertySet |
212 | | void SAL_CALL WrappedPropertySet::setPropertyValues( const Sequence< OUString >& rNameSeq, const Sequence< Any >& rValueSeq ) |
213 | 0 | { |
214 | 0 | bool bUnknownProperty = false; |
215 | 0 | sal_Int32 nMinCount = std::min( rValueSeq.getLength(), rNameSeq.getLength() ); |
216 | 0 | for(sal_Int32 nN=0; nN<nMinCount; nN++) |
217 | 0 | { |
218 | 0 | try |
219 | 0 | { |
220 | 0 | setPropertyValue( rNameSeq[nN], rValueSeq[nN] ); |
221 | 0 | } |
222 | 0 | catch( const beans::UnknownPropertyException& ) |
223 | 0 | { |
224 | 0 | DBG_UNHANDLED_EXCEPTION("chart2"); |
225 | 0 | bUnknownProperty = true; |
226 | 0 | } |
227 | 0 | } |
228 | | //todo: store unknown properties elsewhere |
229 | 0 | OSL_ENSURE(!bUnknownProperty,"unknown property"); |
230 | | // if( bUnknownProperty ) |
231 | | // throw beans::UnknownPropertyException(); |
232 | 0 | } |
233 | | Sequence< Any > SAL_CALL WrappedPropertySet::getPropertyValues( const Sequence< OUString >& rNameSeq ) |
234 | 0 | { |
235 | 0 | Sequence< Any > aRetSeq; |
236 | 0 | if( rNameSeq.hasElements() ) |
237 | 0 | { |
238 | 0 | aRetSeq.realloc( rNameSeq.getLength() ); |
239 | 0 | auto pRetSeq = aRetSeq.getArray(); |
240 | 0 | for(sal_Int32 nN=0; nN<rNameSeq.getLength(); nN++) |
241 | 0 | { |
242 | 0 | try |
243 | 0 | { |
244 | 0 | pRetSeq[nN] = getPropertyValue( rNameSeq[nN] ); |
245 | 0 | } |
246 | 0 | catch( const beans::UnknownPropertyException& ) |
247 | 0 | { |
248 | 0 | DBG_UNHANDLED_EXCEPTION("chart2"); |
249 | 0 | } |
250 | 0 | catch( const lang::WrappedTargetException& ) |
251 | 0 | { |
252 | 0 | DBG_UNHANDLED_EXCEPTION("chart2"); |
253 | 0 | } |
254 | 0 | } |
255 | 0 | } |
256 | 0 | return aRetSeq; |
257 | 0 | } |
258 | | void SAL_CALL WrappedPropertySet::addPropertiesChangeListener( const Sequence< OUString >& /* rNameSeq */, const Reference< beans::XPropertiesChangeListener >& /* xListener */ ) |
259 | 0 | { |
260 | 0 | OSL_FAIL("not implemented yet"); |
261 | | //todo |
262 | 0 | } |
263 | | void SAL_CALL WrappedPropertySet::removePropertiesChangeListener( const Reference< beans::XPropertiesChangeListener >& /* xListener */ ) |
264 | 0 | { |
265 | 0 | OSL_FAIL("not implemented yet"); |
266 | | //todo |
267 | 0 | } |
268 | | void SAL_CALL WrappedPropertySet::firePropertiesChangeEvent( const Sequence< OUString >& /* rNameSeq */, const Reference< beans::XPropertiesChangeListener >& /* xListener */ ) |
269 | 0 | { |
270 | 0 | OSL_FAIL("not implemented yet"); |
271 | | //todo |
272 | 0 | } |
273 | | |
274 | | //XPropertyState |
275 | | beans::PropertyState SAL_CALL WrappedPropertySet::getPropertyState( const OUString& rPropertyName ) |
276 | 0 | { |
277 | 0 | beans::PropertyState aState( beans::PropertyState_DIRECT_VALUE ); |
278 | |
|
279 | 0 | Reference< beans::XPropertyState > xInnerPropertyState( getInnerPropertyState() ); |
280 | 0 | if( xInnerPropertyState.is() ) |
281 | 0 | { |
282 | 0 | const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName ); |
283 | 0 | if( pWrappedProperty ) |
284 | 0 | aState = pWrappedProperty->getPropertyState( xInnerPropertyState ); |
285 | 0 | else |
286 | 0 | aState = xInnerPropertyState->getPropertyState( rPropertyName ); |
287 | 0 | } |
288 | 0 | return aState; |
289 | 0 | } |
290 | | |
291 | | const WrappedProperty* WrappedPropertySet::getWrappedProperty( const OUString& rOuterName ) |
292 | 0 | { |
293 | 0 | sal_Int32 nHandle = getInfoHelper().getHandleByName( rOuterName ); |
294 | 0 | return getWrappedProperty( nHandle ); |
295 | 0 | } |
296 | | |
297 | | const WrappedProperty* WrappedPropertySet::getWrappedProperty( sal_Int32 nHandle ) |
298 | 0 | { |
299 | 0 | tWrappedPropertyMap::const_iterator aFound( getWrappedPropertyMap().find( nHandle ) ); |
300 | 0 | if( aFound != getWrappedPropertyMap().end() ) |
301 | 0 | return (*aFound).second.get(); |
302 | 0 | return nullptr; |
303 | 0 | } |
304 | | |
305 | | Sequence< beans::PropertyState > SAL_CALL WrappedPropertySet::getPropertyStates( const Sequence< OUString >& rNameSeq ) |
306 | 0 | { |
307 | 0 | Sequence< beans::PropertyState > aRetSeq; |
308 | 0 | if( rNameSeq.hasElements() ) |
309 | 0 | { |
310 | 0 | aRetSeq.realloc( rNameSeq.getLength() ); |
311 | 0 | auto pRetSeq = aRetSeq.getArray(); |
312 | 0 | for(sal_Int32 nN=0; nN<rNameSeq.getLength(); nN++) |
313 | 0 | { |
314 | 0 | pRetSeq[nN] = getPropertyState( rNameSeq[nN] ); |
315 | 0 | } |
316 | 0 | } |
317 | 0 | return aRetSeq; |
318 | 0 | } |
319 | | |
320 | | void SAL_CALL WrappedPropertySet::setPropertyToDefault( const OUString& rPropertyName ) |
321 | 0 | { |
322 | 0 | Reference< beans::XPropertyState > xInnerPropertyState( getInnerPropertyState() ); |
323 | 0 | if( xInnerPropertyState.is() ) |
324 | 0 | { |
325 | 0 | const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName ); |
326 | 0 | if( pWrappedProperty ) |
327 | 0 | pWrappedProperty->setPropertyToDefault( xInnerPropertyState ); |
328 | 0 | else |
329 | 0 | xInnerPropertyState->setPropertyToDefault( rPropertyName ); |
330 | 0 | } |
331 | 0 | } |
332 | | Any SAL_CALL WrappedPropertySet::getPropertyDefault( const OUString& rPropertyName ) |
333 | 0 | { |
334 | 0 | Any aRet; |
335 | 0 | Reference< beans::XPropertyState > xInnerPropertyState( getInnerPropertyState() ); |
336 | 0 | if( xInnerPropertyState.is() ) |
337 | 0 | { |
338 | 0 | const WrappedProperty* pWrappedProperty = getWrappedProperty( rPropertyName ); |
339 | 0 | if( pWrappedProperty ) |
340 | 0 | aRet = pWrappedProperty->getPropertyDefault(xInnerPropertyState); |
341 | 0 | else |
342 | 0 | aRet = xInnerPropertyState->getPropertyDefault( rPropertyName ); |
343 | 0 | } |
344 | 0 | return aRet; |
345 | 0 | } |
346 | | |
347 | | //XMultiPropertyStates |
348 | | void SAL_CALL WrappedPropertySet::setAllPropertiesToDefault( ) |
349 | 0 | { |
350 | 0 | const Sequence< beans::Property >& rPropSeq = getPropertySequence(); |
351 | 0 | for(beans::Property const & prop : rPropSeq) |
352 | 0 | { |
353 | 0 | setPropertyToDefault( prop.Name ); |
354 | 0 | } |
355 | 0 | } |
356 | | void SAL_CALL WrappedPropertySet::setPropertiesToDefault( const Sequence< OUString >& rNameSeq ) |
357 | 0 | { |
358 | 0 | for(OUString const & s : rNameSeq) |
359 | 0 | { |
360 | 0 | setPropertyToDefault( s ); |
361 | 0 | } |
362 | 0 | } |
363 | | Sequence< Any > SAL_CALL WrappedPropertySet::getPropertyDefaults( const Sequence< OUString >& rNameSeq ) |
364 | 0 | { |
365 | 0 | Sequence< Any > aRetSeq; |
366 | 0 | if( rNameSeq.hasElements() ) |
367 | 0 | { |
368 | 0 | aRetSeq.realloc( rNameSeq.getLength() ); |
369 | 0 | auto pRetSeq = aRetSeq.getArray(); |
370 | 0 | for(sal_Int32 nN=0; nN<rNameSeq.getLength(); nN++) |
371 | 0 | { |
372 | 0 | pRetSeq[nN] = getPropertyDefault( rNameSeq[nN] ); |
373 | 0 | } |
374 | 0 | } |
375 | 0 | return aRetSeq; |
376 | 0 | } |
377 | | |
378 | | ::cppu::IPropertyArrayHelper& WrappedPropertySet::getInfoHelper() |
379 | 0 | { |
380 | 0 | ::cppu::OPropertyArrayHelper* p = m_pPropertyArrayHelper.get(); |
381 | 0 | if(!p) |
382 | 0 | { |
383 | 0 | ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );//do not use different mutex than is already used for static property sequence |
384 | 0 | p = m_pPropertyArrayHelper.get(); |
385 | 0 | if(!p) |
386 | 0 | { |
387 | 0 | p = new ::cppu::OPropertyArrayHelper( getPropertySequence(), true ); |
388 | 0 | OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); |
389 | 0 | m_pPropertyArrayHelper.reset(p); |
390 | 0 | } |
391 | 0 | } |
392 | 0 | else |
393 | 0 | { |
394 | 0 | OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); |
395 | 0 | } |
396 | 0 | return *m_pPropertyArrayHelper; |
397 | 0 | } |
398 | | |
399 | | tWrappedPropertyMap& WrappedPropertySet::getWrappedPropertyMap() |
400 | 0 | { |
401 | 0 | tWrappedPropertyMap* p = m_pWrappedPropertyMap.get(); |
402 | 0 | if(!p) |
403 | 0 | { |
404 | 0 | ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );//do not use different mutex than is already used for static property sequence |
405 | 0 | p = m_pWrappedPropertyMap.get(); |
406 | 0 | if(!p) |
407 | 0 | { |
408 | 0 | std::vector< std::unique_ptr<WrappedProperty> > aPropList( createWrappedProperties() ); |
409 | 0 | p = new tWrappedPropertyMap; |
410 | |
|
411 | 0 | for (auto & elem : aPropList) |
412 | 0 | { |
413 | 0 | sal_Int32 nHandle = getInfoHelper().getHandleByName( elem->getOuterName() ); |
414 | |
|
415 | 0 | if( nHandle == -1 ) |
416 | 0 | { |
417 | 0 | OSL_FAIL( "missing property in property list" ); |
418 | 0 | } |
419 | 0 | else if( p->find( nHandle ) != p->end() ) |
420 | 0 | { |
421 | | //duplicate Wrapped property |
422 | 0 | OSL_FAIL( "duplicate Wrapped property" ); |
423 | 0 | } |
424 | 0 | else |
425 | 0 | (*p)[ nHandle ] = std::move(elem); |
426 | 0 | } |
427 | |
|
428 | 0 | OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); |
429 | 0 | m_pWrappedPropertyMap.reset(p); |
430 | 0 | } |
431 | 0 | } |
432 | 0 | else |
433 | 0 | { |
434 | 0 | OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); |
435 | 0 | } |
436 | 0 | return *m_pWrappedPropertyMap; |
437 | 0 | } |
438 | | |
439 | | } //namespace chart |
440 | | |
441 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |