Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/accessibility/proxyaggregation.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 <sal/config.h>
21
22
#include "proxyaggregation.hxx"
23
24
#include <cassert>
25
26
#include <com/sun/star/reflection/ProxyFactory.hpp>
27
28
29
namespace accessibility
30
{
31
32
33
    using namespace ::com::sun::star::uno;
34
    using namespace ::com::sun::star::lang;
35
    using namespace ::com::sun::star::reflection;
36
37
    OProxyAggregation::OProxyAggregation( const Reference< XComponentContext >& _rxContext )
38
0
        :m_xContext( _rxContext )
39
0
    {
40
0
    }
41
42
43
    void OProxyAggregation::baseAggregateProxyFor( const Reference< XInterface >& _rxComponent, oslInterlockedCount& _rRefCount,
44
            ::cppu::OWeakObject& _rDelegator )
45
0
    {
46
        // first a factory for the proxy
47
0
        Reference< XProxyFactory > xFactory = ProxyFactory::create( m_xContext );
48
49
        // then the proxy itself
50
0
        { // i36686 OJ: achieve the destruction of the temporary -> otherwise it leads to _rRefCount -= 2
51
0
            m_xProxyAggregate = xFactory->createProxy( _rxComponent );
52
0
        }
53
0
        if ( m_xProxyAggregate.is() )
54
0
            m_xProxyAggregate->queryAggregation( cppu::UnoType<decltype(m_xProxyTypeAccess)>::get() ) >>= m_xProxyTypeAccess;
55
56
        // aggregate the proxy
57
0
        osl_atomic_increment( &_rRefCount );
58
0
        if ( m_xProxyAggregate.is() )
59
0
        {
60
            // At this point in time, the proxy has a ref count of exactly two - in m_xControlContextProxy,
61
            // and in m_xProxyTypeAccess.
62
            // Remember to _not_ reset these members unless the delegator of the proxy has been reset, too!
63
0
            m_xProxyAggregate->setDelegator( _rDelegator );
64
0
        }
65
0
        osl_atomic_decrement( &_rRefCount );
66
0
    }
67
68
69
    Any SAL_CALL OProxyAggregation::queryAggregation( const Type& _rType )
70
0
    {
71
0
        return m_xProxyAggregate.is() ? m_xProxyAggregate->queryAggregation( _rType ) : Any();
72
0
    }
73
74
75
    Sequence< Type > SAL_CALL OProxyAggregation::getTypes(  )
76
0
    {
77
0
        Sequence< Type > aTypes;
78
0
        if ( m_xProxyAggregate.is() )
79
0
        {
80
0
            if ( m_xProxyTypeAccess.is() )
81
0
                aTypes = m_xProxyTypeAccess->getTypes();
82
0
        }
83
0
        return aTypes;
84
0
    }
85
86
87
    OProxyAggregation::~OProxyAggregation()
88
0
    {
89
0
        if ( m_xProxyAggregate.is() )
90
0
            m_xProxyAggregate->setDelegator( nullptr );
91
0
        m_xProxyAggregate.clear();
92
0
        m_xProxyTypeAccess.clear();
93
            // this should remove the _two_only_ "real" references (means not delegated to
94
            // ourself) to this proxy, and thus delete it
95
0
    }
96
97
    OComponentProxyAggregationHelper::OComponentProxyAggregationHelper( const Reference< XComponentContext >& _rxContext,
98
        ::cppu::OBroadcastHelper& _rBHelper )
99
0
        :OProxyAggregation( _rxContext )
100
0
        ,m_rBHelper( _rBHelper )
101
0
    {
102
0
        OSL_ENSURE( _rxContext.is(), "OComponentProxyAggregationHelper::OComponentProxyAggregationHelper: invalid arguments!" );
103
0
    }
104
105
106
    void OComponentProxyAggregationHelper::componentAggregateProxyFor(
107
        const Reference< XComponent >& _rxComponent, oslInterlockedCount& _rRefCount,
108
        ::cppu::OWeakObject& _rDelegator )
109
0
    {
110
0
        OSL_ENSURE( _rxComponent.is(), "OComponentProxyAggregationHelper::componentAggregateProxyFor: invalid inner component!" );
111
0
        m_xInner = _rxComponent;
112
113
        // aggregate a proxy for the object
114
0
        baseAggregateProxyFor( m_xInner, _rRefCount, _rDelegator );
115
116
        // add as event listener to the inner context, because we want to be notified of disposals
117
0
        osl_atomic_increment( &_rRefCount );
118
0
        {
119
0
            if ( m_xInner.is() )
120
0
                m_xInner->addEventListener( this );
121
0
        }
122
0
        osl_atomic_decrement( &_rRefCount );
123
0
    }
124
125
126
    Any SAL_CALL OComponentProxyAggregationHelper::queryInterface( const Type& _rType )
127
0
    {
128
0
        Any aReturn( BASE::queryInterface( _rType ) );
129
0
        if ( !aReturn.hasValue() )
130
0
            aReturn = OProxyAggregation::queryAggregation( _rType );
131
0
        return aReturn;
132
0
    }
133
134
135
    IMPLEMENT_FORWARD_XTYPEPROVIDER2( OComponentProxyAggregationHelper, BASE, OProxyAggregation )
136
137
138
    OComponentProxyAggregationHelper::~OComponentProxyAggregationHelper( )
139
0
    {
140
0
        OSL_ENSURE( m_rBHelper.bDisposed, "OComponentProxyAggregationHelper::~OComponentProxyAggregationHelper: you should dispose your derived class in the dtor, if necessary!" );
141
            // if this asserts, add the following to your derived class dtor:
142
143
            // if ( !m_rBHelper.bDisposed )
144
            // {
145
            //   acquire(); // to prevent duplicate dtor calls
146
            //   dispose();
147
            // }
148
149
0
        m_xInner.clear();
150
0
    }
151
152
153
    void SAL_CALL OComponentProxyAggregationHelper::disposing( const EventObject& _rSource )
154
0
    {
155
0
        if ( _rSource.Source == m_xInner )
156
0
        {   // it's our inner context which is dying -> dispose ourself
157
0
            if ( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose )
158
0
            {   // (if necessary only, of course)
159
0
                dispose();
160
0
            }
161
0
        }
162
0
    }
163
164
165
    void SAL_CALL OComponentProxyAggregationHelper::dispose()
166
0
    {
167
0
        ::osl::MutexGuard aGuard( m_rBHelper.rMutex );
168
169
        // dispose our inner context
170
        // before we do this, remove ourself as listener - else in disposing( EventObject ), we
171
        // would dispose ourself a second time
172
0
        if ( m_xInner.is() )
173
0
        {
174
0
            m_xInner->removeEventListener( this );
175
0
            m_xInner->dispose();
176
0
            m_xInner.clear();
177
0
        }
178
0
    }
179
180
    OComponentProxyAggregation::OComponentProxyAggregation( const Reference< XComponentContext >& _rxContext,
181
            const Reference< XComponent >& _rxComponent )
182
0
        :WeakComponentImplHelperBase( m_aMutex )
183
0
        ,OComponentProxyAggregationHelper( _rxContext, rBHelper )
184
0
    {
185
0
        OSL_ENSURE( _rxComponent.is(), "OComponentProxyAggregation::OComponentProxyAggregation: accessible is no XComponent!" );
186
0
        if ( _rxComponent.is() )
187
0
            componentAggregateProxyFor( _rxComponent, m_refCount, *this );
188
0
    }
189
190
191
    OComponentProxyAggregation::~OComponentProxyAggregation()
192
0
    {
193
0
        if ( !rBHelper.bDisposed )
194
0
        {
195
0
            acquire();  // to prevent duplicate dtor calls
196
0
            dispose();
197
0
        }
198
0
    }
199
200
201
    IMPLEMENT_FORWARD_XINTERFACE2( OComponentProxyAggregation, WeakComponentImplHelperBase, OComponentProxyAggregationHelper )
202
203
204
    IMPLEMENT_GET_IMPLEMENTATION_ID( OComponentProxyAggregation )
205
206
207
    Sequence< Type > SAL_CALL OComponentProxyAggregation::getTypes(  )
208
0
    {
209
0
        return comphelper::concatSequences(
210
0
                OComponentProxyAggregationHelper::getTypes(),
211
                // append XComponent, coming from WeakComponentImplHelperBase
212
0
                std::initializer_list<Type>{ cppu::UnoType<XComponent>::get() });
213
0
    }
214
215
216
    void SAL_CALL OComponentProxyAggregation::disposing( const EventObject& _rSource )
217
0
    {
218
        // Simply disambiguate---this is necessary for MSVC to distinguish
219
        // "disposing(EventObject)" from "disposing()"; but it is also a good
220
        // place to check for recursive calls that would be caused by an object
221
        // being registered as an XEventListener at itself (cf. rhbz#928568):
222
0
        assert(_rSource.Source != static_cast< cppu::OWeakObject * >(this));
223
0
        OComponentProxyAggregationHelper::disposing( _rSource );
224
0
    }
225
226
227
    void SAL_CALL OComponentProxyAggregation::disposing()
228
0
    {
229
        // call the dispose-functionality of the base, which will dispose our aggregated component
230
0
        OComponentProxyAggregationHelper::dispose();
231
0
    }
232
233
234
    void SAL_CALL OComponentProxyAggregation::dispose()
235
0
    {
236
        // simply disambiguate
237
0
        WeakComponentImplHelperBase::dispose();
238
0
    }
239
240
241
}   // namespace accessibility
242
243
244
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */