cid#1607171 Data race condition
[LibreOffice.git] / ucb / source / ucp / hierarchy / hierarchydatasupplier.cxx
blob387f91a670e12d35c79e8c9680cfac2a65dc7ab6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 /**************************************************************************
22 TODO
23 **************************************************************************
25 *************************************************************************/
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"
34 using namespace com::sun::star;
35 using namespace hierarchy_ucp;
39 HierarchyResultSetDataSupplier::HierarchyResultSetDataSupplier(
40 const uno::Reference< uno::XComponentContext >& rxContext,
41 const rtl::Reference< HierarchyContent >& rContent,
42 sal_Int32 nOpenMode )
43 : m_xContent( rContent ), m_xContext( rxContext ),
44 m_aFolder( rxContext,
45 static_cast< HierarchyContentProvider * >(
46 rContent->getProvider().get() ),
47 rContent->getIdentifier()->getContentIdentifier() ),
48 m_nOpenMode( nOpenMode ), m_bCountFinal( false )
53 // virtual
54 HierarchyResultSetDataSupplier::~HierarchyResultSetDataSupplier()
59 // virtual
60 OUString HierarchyResultSetDataSupplier::queryContentIdentifierString(
61 std::unique_lock<std::mutex>& rResultSetGuard,
62 sal_uInt32 nIndex )
64 std::unique_lock aGuard( m_aMutex );
65 return queryContentIdentifierStringImpl(rResultSetGuard, aGuard, nIndex);
68 OUString HierarchyResultSetDataSupplier::queryContentIdentifierStringImpl(
69 std::unique_lock<std::mutex>& rResultSetGuard,
70 std::unique_lock<std::mutex>& rGuard,
71 sal_uInt32 nIndex )
73 if ( nIndex < m_aResults.size() )
75 OUString aId = m_aResults[ nIndex ]->aId;
76 if ( !aId.isEmpty() )
78 // Already cached.
79 return aId;
83 if ( getResultImpl( rResultSetGuard, rGuard, nIndex ) )
85 OUString aId
86 = m_xContent->getIdentifier()->getContentIdentifier();
88 if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
89 aId += "/";
91 aId += m_aResults[ nIndex ]->aData.getName();
93 m_aResults[ nIndex ]->aId = aId;
94 return aId;
96 return OUString();
100 // virtual
101 uno::Reference< ucb::XContentIdentifier >
102 HierarchyResultSetDataSupplier::queryContentIdentifier( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
104 std::unique_lock aGuard( m_aMutex );
106 if ( nIndex < m_aResults.size() )
108 uno::Reference< ucb::XContentIdentifier > xId
109 = m_aResults[ nIndex ]->xId;
110 if ( xId.is() )
112 // Already cached.
113 return xId;
117 OUString aId = queryContentIdentifierStringImpl( rResultSetGuard, aGuard, nIndex );
118 if ( !aId.isEmpty() )
120 uno::Reference< ucb::XContentIdentifier > xId
121 = new ::ucbhelper::ContentIdentifier( aId );
122 m_aResults[ nIndex ]->xId = xId;
123 return xId;
125 return uno::Reference< ucb::XContentIdentifier >();
129 // virtual
130 uno::Reference< ucb::XContent >
131 HierarchyResultSetDataSupplier::queryContent( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
133 std::unique_lock aGuard( m_aMutex );
135 if ( nIndex < m_aResults.size() )
137 uno::Reference< ucb::XContent > xContent
138 = m_aResults[ nIndex ]->xContent;
139 if ( xContent.is() )
141 // Already cached.
142 return xContent;
146 uno::Reference< ucb::XContentIdentifier > xId
147 = queryContentIdentifier( rResultSetGuard, nIndex );
148 if ( xId.is() )
152 uno::Reference< ucb::XContent > xContent
153 = m_xContent->getProvider()->queryContent( xId );
154 m_aResults[ nIndex ]->xContent = xContent;
155 return xContent;
158 catch ( ucb::IllegalIdentifierException const & )
162 return uno::Reference< ucb::XContent >();
166 // virtual
167 bool HierarchyResultSetDataSupplier::getResult( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
169 std::unique_lock aGuard( m_aMutex );
170 return getResultImpl(rResultSetGuard, aGuard, nIndex);
173 bool HierarchyResultSetDataSupplier::getResultImpl( std::unique_lock<std::mutex>& rResultSetGuard, std::unique_lock<std::mutex>& rGuard, sal_uInt32 nIndex )
175 if ( m_aResults.size() > nIndex )
177 // Result already present.
178 return true;
181 // Result not (yet) present.
183 if ( m_bCountFinal )
184 return false;
186 // Try to obtain result...
188 sal_uInt32 nOldCount = m_aResults.size();
189 bool bFound = false;
190 sal_uInt32 nPos = nOldCount;
192 while ( m_aFolder.next( m_aIterator ) )
194 const HierarchyEntryData& rResult = *m_aIterator;
195 if ( checkResult( rResult ) )
197 m_aResults.emplace_back( new ResultListEntry( rResult ) );
199 if ( nPos == nIndex )
201 // Result obtained.
202 bFound = true;
203 break;
206 nPos++;
209 if ( !bFound )
210 m_bCountFinal = true;
212 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet();
213 if ( xResultSet.is() )
215 // Callbacks follow!
216 rGuard.unlock();
218 if ( nOldCount < m_aResults.size() )
219 xResultSet->rowCountChanged(rResultSetGuard,
220 nOldCount, m_aResults.size() );
222 if ( m_bCountFinal )
223 xResultSet->rowCountFinal(rResultSetGuard);
225 rGuard.lock();
228 return bFound;
232 // virtual
233 sal_uInt32 HierarchyResultSetDataSupplier::totalCount(std::unique_lock<std::mutex>& rResultSetGuard)
235 std::unique_lock aGuard( m_aMutex );
237 if ( m_bCountFinal )
238 return m_aResults.size();
240 sal_uInt32 nOldCount = m_aResults.size();
242 while ( m_aFolder.next( m_aIterator ) )
244 const HierarchyEntryData& rResult = *m_aIterator;
245 if ( checkResult( rResult ) )
246 m_aResults.emplace_back( new ResultListEntry( rResult ) );
249 m_bCountFinal = true;
251 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet();
252 if ( xResultSet.is() )
254 // Callbacks follow!
255 aGuard.unlock();
257 if ( nOldCount < m_aResults.size() )
258 xResultSet->rowCountChanged(rResultSetGuard,
259 nOldCount, m_aResults.size() );
261 xResultSet->rowCountFinal(rResultSetGuard);
264 return m_aResults.size();
268 // virtual
269 sal_uInt32 HierarchyResultSetDataSupplier::currentCount()
271 return m_aResults.size();
275 // virtual
276 bool HierarchyResultSetDataSupplier::isCountFinal()
278 return m_bCountFinal;
282 // virtual
283 uno::Reference< sdbc::XRow >
284 HierarchyResultSetDataSupplier::queryPropertyValues( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
286 std::unique_lock aGuard( m_aMutex );
288 if ( nIndex < m_aResults.size() )
290 uno::Reference< sdbc::XRow > xRow
291 = m_aResults[ nIndex ]->xRow;
292 if ( xRow.is() )
294 // Already cached.
295 return xRow;
299 if ( getResultImpl( rResultSetGuard, aGuard, nIndex ) )
301 HierarchyContentProperties aData(
302 m_aResults[ nIndex ]->aData );
304 uno::Reference< sdbc::XRow > xRow
305 = HierarchyContent::getPropertyValues(
306 m_xContext,
307 getResultSet()->getProperties(),
308 aData,
309 static_cast< HierarchyContentProvider * >(
310 m_xContent->getProvider().get() ),
311 queryContentIdentifierStringImpl( rResultSetGuard, aGuard, nIndex ) );
312 m_aResults[ nIndex ]->xRow = xRow;
313 return xRow;
316 return uno::Reference< sdbc::XRow >();
320 // virtual
321 void HierarchyResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
323 std::unique_lock aGuard( m_aMutex );
325 if ( nIndex < m_aResults.size() )
326 m_aResults[ nIndex ]->xRow.clear();
330 // virtual
331 void HierarchyResultSetDataSupplier::close()
336 // virtual
337 void HierarchyResultSetDataSupplier::validate()
342 bool HierarchyResultSetDataSupplier::checkResult(
343 const HierarchyEntryData& rResult )
345 switch ( m_nOpenMode )
347 case ucb::OpenMode::FOLDERS:
348 if ( rResult.getType() == HierarchyEntryData::LINK )
350 // Entry is a link.
351 return false;
353 break;
355 case ucb::OpenMode::DOCUMENTS:
356 if ( rResult.getType() == HierarchyEntryData::FOLDER )
358 // Entry is a folder.
359 return false;
361 break;
363 case ucb::OpenMode::ALL:
364 default:
365 break;
368 return true;
371 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */