Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/ucb/source/ucp/hierarchy/hierarchydatasupplier.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
21
/**************************************************************************
22
                                TODO
23
 **************************************************************************
24
25
 *************************************************************************/
26
27
#include <com/sun/star/ucb/IllegalIdentifierException.hpp>
28
#include <com/sun/star/ucb/OpenMode.hpp>
29
#include <ucbhelper/contentidentifier.hxx>
30
#include "hierarchydatasupplier.hxx"
31
#include "hierarchyprovider.hxx"
32
#include "hierarchycontent.hxx"
33
34
using namespace com::sun::star;
35
using namespace hierarchy_ucp;
36
37
38
39
HierarchyResultSetDataSupplier::HierarchyResultSetDataSupplier(
40
                const uno::Reference< uno::XComponentContext >& rxContext,
41
                const rtl::Reference< HierarchyContent >& rContent,
42
                sal_Int32 nOpenMode )
43
0
: m_xContent( rContent ), m_xContext( rxContext ),
44
0
  m_aFolder( rxContext,
45
0
             static_cast< HierarchyContentProvider * >(
46
0
                 rContent->getProvider().get() ),
47
0
             rContent->getIdentifier()->getContentIdentifier() ),
48
0
  m_nOpenMode( nOpenMode ), m_bCountFinal( false )
49
0
{
50
0
}
51
52
53
// virtual
54
HierarchyResultSetDataSupplier::~HierarchyResultSetDataSupplier()
55
0
{
56
0
}
57
58
59
// virtual
60
OUString HierarchyResultSetDataSupplier::queryContentIdentifierString(
61
                                                        std::unique_lock<std::mutex>& rResultSetGuard,
62
                                                        sal_uInt32 nIndex )
63
0
{
64
0
    std::unique_lock aGuard( m_aMutex );
65
0
    return queryContentIdentifierStringImpl(rResultSetGuard, aGuard, nIndex);
66
0
}
67
68
OUString HierarchyResultSetDataSupplier::queryContentIdentifierStringImpl(
69
                                            std::unique_lock<std::mutex>& rResultSetGuard,
70
                                            std::unique_lock<std::mutex>& rGuard,
71
                                            sal_uInt32 nIndex )
72
0
{
73
0
    if ( nIndex < m_aResults.size() )
74
0
    {
75
0
        OUString aId = m_aResults[ nIndex ]->aId;
76
0
        if ( !aId.isEmpty() )
77
0
        {
78
            // Already cached.
79
0
            return aId;
80
0
        }
81
0
    }
82
83
0
    if ( getResultImpl( rResultSetGuard, rGuard, nIndex ) )
84
0
    {
85
0
        OUString aId
86
0
            = m_xContent->getIdentifier()->getContentIdentifier();
87
88
0
        if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
89
0
            aId += "/";
90
91
0
        aId += m_aResults[ nIndex ]->aData.getName();
92
93
0
        m_aResults[ nIndex ]->aId = aId;
94
0
        return aId;
95
0
    }
96
0
    return OUString();
97
0
}
98
99
100
// virtual
101
uno::Reference< ucb::XContentIdentifier >
102
HierarchyResultSetDataSupplier::queryContentIdentifier( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
103
0
{
104
0
    std::unique_lock aGuard( m_aMutex );
105
106
0
    if ( nIndex < m_aResults.size() )
107
0
    {
108
0
        uno::Reference< ucb::XContentIdentifier > xId
109
0
                                = m_aResults[ nIndex ]->xId;
110
0
        if ( xId.is() )
111
0
        {
112
            // Already cached.
113
0
            return xId;
114
0
        }
115
0
    }
116
117
0
    OUString aId = queryContentIdentifierStringImpl( rResultSetGuard, aGuard, nIndex );
118
0
    if ( !aId.isEmpty() )
119
0
    {
120
0
        uno::Reference< ucb::XContentIdentifier > xId
121
0
            = new ::ucbhelper::ContentIdentifier( aId );
122
0
        m_aResults[ nIndex ]->xId = xId;
123
0
        return xId;
124
0
    }
125
0
    return uno::Reference< ucb::XContentIdentifier >();
126
0
}
127
128
129
// virtual
130
uno::Reference< ucb::XContent >
131
HierarchyResultSetDataSupplier::queryContent( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
132
0
{
133
0
    std::unique_lock aGuard( m_aMutex );
134
135
0
    if ( nIndex < m_aResults.size() )
136
0
    {
137
0
        uno::Reference< ucb::XContent > xContent
138
0
                                = m_aResults[ nIndex ]->xContent;
139
0
        if ( xContent.is() )
140
0
        {
141
            // Already cached.
142
0
            return xContent;
143
0
        }
144
0
    }
145
146
0
    uno::Reference< ucb::XContentIdentifier > xId
147
0
        = queryContentIdentifier( rResultSetGuard, nIndex );
148
0
    if ( xId.is() )
149
0
    {
150
0
        try
151
0
        {
152
0
            uno::Reference< ucb::XContent > xContent
153
0
                = m_xContent->getProvider()->queryContent( xId );
154
0
            m_aResults[ nIndex ]->xContent = xContent;
155
0
            return xContent;
156
157
0
        }
158
0
        catch ( ucb::IllegalIdentifierException const & )
159
0
        {
160
0
        }
161
0
    }
162
0
    return uno::Reference< ucb::XContent >();
163
0
}
164
165
166
// virtual
167
bool HierarchyResultSetDataSupplier::getResult( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
168
0
{
169
0
    std::unique_lock aGuard( m_aMutex );
170
0
    return getResultImpl(rResultSetGuard, aGuard, nIndex);
171
0
}
172
173
bool HierarchyResultSetDataSupplier::getResultImpl( std::unique_lock<std::mutex>& rResultSetGuard, std::unique_lock<std::mutex>& rGuard, sal_uInt32 nIndex )
174
0
{
175
0
    if ( m_aResults.size() > nIndex )
176
0
    {
177
        // Result already present.
178
0
        return true;
179
0
    }
180
181
    // Result not (yet) present.
182
183
0
    if ( m_bCountFinal )
184
0
        return false;
185
186
    // Try to obtain result...
187
188
0
    sal_uInt32 nOldCount = m_aResults.size();
189
0
    bool bFound = false;
190
0
    sal_uInt32 nPos = nOldCount;
191
192
0
    while ( m_aFolder.next( m_aIterator ) )
193
0
    {
194
0
        const HierarchyEntryData& rResult = *m_aIterator;
195
0
        if ( checkResult( rResult ) )
196
0
        {
197
0
            m_aResults.emplace_back( new ResultListEntry( rResult ) );
198
199
0
            if ( nPos == nIndex )
200
0
            {
201
                // Result obtained.
202
0
                bFound = true;
203
0
                break;
204
0
            }
205
0
        }
206
0
        nPos++;
207
0
    }
208
209
0
    if ( !bFound )
210
0
        m_bCountFinal = true;
211
212
0
    rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet();
213
0
    if ( xResultSet.is() )
214
0
    {
215
        // Callbacks follow!
216
0
        rGuard.unlock();
217
218
0
        if ( nOldCount < m_aResults.size() )
219
0
            xResultSet->rowCountChanged(rResultSetGuard,
220
0
                                    nOldCount, m_aResults.size() );
221
222
0
        if ( m_bCountFinal )
223
0
            xResultSet->rowCountFinal(rResultSetGuard);
224
225
0
        rGuard.lock();
226
0
    }
227
228
0
    return bFound;
229
0
}
230
231
232
// virtual
233
sal_uInt32 HierarchyResultSetDataSupplier::totalCount(std::unique_lock<std::mutex>& rResultSetGuard)
234
0
{
235
0
    std::unique_lock aGuard( m_aMutex );
236
237
0
    if ( m_bCountFinal )
238
0
        return m_aResults.size();
239
240
0
    sal_uInt32 nOldCount = m_aResults.size();
241
242
0
    while ( m_aFolder.next( m_aIterator ) )
243
0
    {
244
0
        const HierarchyEntryData& rResult = *m_aIterator;
245
0
        if ( checkResult( rResult ) )
246
0
            m_aResults.emplace_back( new ResultListEntry( rResult ) );
247
0
    }
248
249
0
    m_bCountFinal = true;
250
251
0
    rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet();
252
0
    if ( xResultSet.is() )
253
0
    {
254
        // Callbacks follow!
255
0
        aGuard.unlock();
256
257
0
        if ( nOldCount < m_aResults.size() )
258
0
            xResultSet->rowCountChanged(rResultSetGuard,
259
0
                                    nOldCount, m_aResults.size() );
260
261
0
        xResultSet->rowCountFinal(rResultSetGuard);
262
0
    }
263
264
0
    return m_aResults.size();
265
0
}
266
267
268
// virtual
269
sal_uInt32 HierarchyResultSetDataSupplier::currentCount()
270
0
{
271
0
    return m_aResults.size();
272
0
}
273
274
275
// virtual
276
bool HierarchyResultSetDataSupplier::isCountFinal()
277
0
{
278
0
    return m_bCountFinal;
279
0
}
280
281
282
// virtual
283
uno::Reference< sdbc::XRow >
284
HierarchyResultSetDataSupplier::queryPropertyValues( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex  )
285
0
{
286
0
    std::unique_lock aGuard( m_aMutex );
287
288
0
    if ( nIndex < m_aResults.size() )
289
0
    {
290
0
        uno::Reference< sdbc::XRow > xRow
291
0
            = m_aResults[ nIndex ]->xRow;
292
0
        if ( xRow.is() )
293
0
        {
294
            // Already cached.
295
0
            return xRow;
296
0
        }
297
0
    }
298
299
0
    if ( getResultImpl( rResultSetGuard, aGuard, nIndex ) )
300
0
    {
301
0
        HierarchyContentProperties aData(
302
0
            m_aResults[ nIndex ]->aData );
303
304
0
        uno::Reference< sdbc::XRow > xRow
305
0
            = HierarchyContent::getPropertyValues(
306
0
                m_xContext,
307
0
                getResultSet()->getProperties(),
308
0
                aData,
309
0
                static_cast< HierarchyContentProvider * >(
310
0
                    m_xContent->getProvider().get() ),
311
0
                queryContentIdentifierStringImpl( rResultSetGuard, aGuard, nIndex ) );
312
0
        m_aResults[ nIndex ]->xRow = xRow;
313
0
        return xRow;
314
0
    }
315
316
0
    return uno::Reference< sdbc::XRow >();
317
0
}
318
319
320
// virtual
321
void HierarchyResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
322
0
{
323
0
    std::unique_lock aGuard( m_aMutex );
324
325
0
    if ( nIndex < m_aResults.size() )
326
0
        m_aResults[ nIndex ]->xRow.clear();
327
0
}
328
329
330
// virtual
331
void HierarchyResultSetDataSupplier::close()
332
0
{
333
0
}
334
335
336
// virtual
337
void HierarchyResultSetDataSupplier::validate()
338
0
{
339
0
}
340
341
342
bool HierarchyResultSetDataSupplier::checkResult(
343
                                    const HierarchyEntryData& rResult )
344
0
{
345
0
    switch ( m_nOpenMode )
346
0
    {
347
0
        case ucb::OpenMode::FOLDERS:
348
0
            if ( rResult.getType() == HierarchyEntryData::LINK )
349
0
            {
350
                // Entry is a link.
351
0
                return false;
352
0
            }
353
0
            break;
354
355
0
        case ucb::OpenMode::DOCUMENTS:
356
0
            if ( rResult.getType() == HierarchyEntryData::FOLDER )
357
0
            {
358
                // Entry is a folder.
359
0
                return false;
360
0
            }
361
0
            break;
362
363
0
        case ucb::OpenMode::ALL:
364
0
        default:
365
0
            break;
366
0
    }
367
368
0
    return true;
369
0
}
370
371
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */