Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */