bump product version to 7.2.5.1
[LibreOffice.git] / ucb / source / ucp / tdoc / tdoc_datasupplier.cxx
blobc7bad1e70ffa3cde58cda28830c9e420878a77b6
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 <vector>
29 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
30 #include <com/sun/star/ucb/ResultSetException.hpp>
31 #include <osl/diagnose.h>
32 #include <ucbhelper/contentidentifier.hxx>
34 #include "tdoc_datasupplier.hxx"
35 #include "tdoc_content.hxx"
37 using namespace com::sun::star;
38 using namespace tdoc_ucp;
40 namespace tdoc_ucp
44 // struct ResultListEntry.
46 namespace {
48 struct ResultListEntry
50 OUString aURL;
51 uno::Reference< ucb::XContentIdentifier > xId;
52 uno::Reference< ucb::XContent > xContent;
53 uno::Reference< sdbc::XRow > xRow;
55 explicit ResultListEntry( const OUString& rURL ) : aURL( rURL ) {}
60 // struct DataSupplier_Impl.
63 struct DataSupplier_Impl
65 osl::Mutex m_aMutex;
66 std::vector< ResultListEntry > m_aResults;
67 rtl::Reference< Content > m_xContent;
68 uno::Reference< uno::XComponentContext > m_xContext;
69 std::unique_ptr<uno::Sequence< OUString > > m_pNamesOfChildren;
70 bool m_bCountFinal;
71 bool m_bThrowException;
73 DataSupplier_Impl(
74 const uno::Reference< uno::XComponentContext >& rxContext,
75 const rtl::Reference< Content >& rContent )
76 : m_xContent( rContent ), m_xContext( rxContext ),
77 m_bCountFinal( false ), m_bThrowException( false )
84 // DataSupplier Implementation.
85 ResultSetDataSupplier::ResultSetDataSupplier(
86 const uno::Reference< uno::XComponentContext >& rxContext,
87 const rtl::Reference< Content >& rContent )
88 : m_pImpl( new DataSupplier_Impl( rxContext, rContent ) )
92 // virtual
93 ResultSetDataSupplier::~ResultSetDataSupplier()
97 // virtual
98 OUString
99 ResultSetDataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
101 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
103 if ( nIndex < m_pImpl->m_aResults.size() )
105 OUString aId = m_pImpl->m_aResults[ nIndex ].aURL;
106 if ( !aId.isEmpty() )
108 // Already cached.
109 return aId;
113 if ( getResult( nIndex ) )
115 // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
116 return m_pImpl->m_aResults[ nIndex ].aURL;
118 return OUString();
121 // virtual
122 uno::Reference< ucb::XContentIdentifier >
123 ResultSetDataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
125 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
127 if ( nIndex < m_pImpl->m_aResults.size() )
129 uno::Reference< ucb::XContentIdentifier > xId
130 = m_pImpl->m_aResults[ nIndex ].xId;
131 if ( xId.is() )
133 // Already cached.
134 return xId;
138 OUString aId = queryContentIdentifierString( nIndex );
139 if ( !aId.isEmpty() )
141 uno::Reference< ucb::XContentIdentifier > xId
142 = new ::ucbhelper::ContentIdentifier( aId );
143 m_pImpl->m_aResults[ nIndex ].xId = xId;
144 return xId;
146 return uno::Reference< ucb::XContentIdentifier >();
149 // virtual
150 uno::Reference< ucb::XContent >
151 ResultSetDataSupplier::queryContent( sal_uInt32 nIndex )
153 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
155 if ( nIndex < m_pImpl->m_aResults.size() )
157 uno::Reference< ucb::XContent > xContent
158 = m_pImpl->m_aResults[ nIndex ].xContent;
159 if ( xContent.is() )
161 // Already cached.
162 return xContent;
166 uno::Reference< ucb::XContentIdentifier > xId
167 = queryContentIdentifier( nIndex );
168 if ( xId.is() )
172 uno::Reference< ucb::XContent > xContent
173 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
174 m_pImpl->m_aResults[ nIndex ].xContent = xContent;
175 return xContent;
178 catch ( ucb::IllegalIdentifierException const & )
182 return uno::Reference< ucb::XContent >();
185 // virtual
186 bool ResultSetDataSupplier::getResult( sal_uInt32 nIndex )
188 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
190 if ( m_pImpl->m_aResults.size() > nIndex )
192 // Result already present.
193 return true;
196 // Result not (yet) present.
198 if ( m_pImpl->m_bCountFinal )
199 return false;
201 // Try to obtain result...
203 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
204 bool bFound = false;
206 if ( queryNamesOfChildren() )
208 for ( sal_uInt32 n = nOldCount;
209 n < sal::static_int_cast<sal_uInt32>(
210 m_pImpl->m_pNamesOfChildren->getLength());
211 ++n )
213 const OUString & rName
214 = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
216 if ( rName.isEmpty() )
218 OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
219 break;
222 // Assemble URL for child.
223 OUString aURL = assembleChildURL( rName );
225 m_pImpl->m_aResults.emplace_back( aURL );
227 if ( n == nIndex )
229 // Result obtained.
230 bFound = true;
231 break;
236 if ( !bFound )
237 m_pImpl->m_bCountFinal = true;
239 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet();
240 if ( xResultSet.is() )
242 // Callbacks follow!
243 aGuard.clear();
245 if ( nOldCount < m_pImpl->m_aResults.size() )
246 xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
248 if ( m_pImpl->m_bCountFinal )
249 xResultSet->rowCountFinal();
252 return bFound;
255 // virtual
256 sal_uInt32 ResultSetDataSupplier::totalCount()
258 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
260 if ( m_pImpl->m_bCountFinal )
261 return m_pImpl->m_aResults.size();
263 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
265 if ( queryNamesOfChildren() )
267 for ( sal_uInt32 n = nOldCount;
268 n < sal::static_int_cast<sal_uInt32>(
269 m_pImpl->m_pNamesOfChildren->getLength());
270 ++n )
272 const OUString & rName
273 = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
275 if ( rName.isEmpty() )
277 OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
278 break;
281 // Assemble URL for child.
282 OUString aURL = assembleChildURL( rName );
284 m_pImpl->m_aResults.emplace_back( aURL );
288 m_pImpl->m_bCountFinal = true;
290 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet();
291 if ( xResultSet.is() )
293 // Callbacks follow!
294 aGuard.clear();
296 if ( nOldCount < m_pImpl->m_aResults.size() )
297 xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
299 xResultSet->rowCountFinal();
302 return m_pImpl->m_aResults.size();
305 // virtual
306 sal_uInt32 ResultSetDataSupplier::currentCount()
308 return m_pImpl->m_aResults.size();
311 // virtual
312 bool ResultSetDataSupplier::isCountFinal()
314 return m_pImpl->m_bCountFinal;
317 // virtual
318 uno::Reference< sdbc::XRow >
319 ResultSetDataSupplier::queryPropertyValues( sal_uInt32 nIndex )
321 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
323 if ( nIndex < m_pImpl->m_aResults.size() )
325 uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ].xRow;
326 if ( xRow.is() )
328 // Already cached.
329 return xRow;
333 if ( getResult( nIndex ) )
335 uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
336 m_pImpl->m_xContext,
337 getResultSet()->getProperties(),
338 m_pImpl->m_xContent->getContentProvider().get(),
339 queryContentIdentifierString( nIndex ) );
340 m_pImpl->m_aResults[ nIndex ].xRow = xRow;
341 return xRow;
344 return uno::Reference< sdbc::XRow >();
347 // virtual
348 void ResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
350 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
352 if ( nIndex < m_pImpl->m_aResults.size() )
353 m_pImpl->m_aResults[ nIndex ].xRow.clear();
356 // virtual
357 void ResultSetDataSupplier::close()
361 // virtual
362 void ResultSetDataSupplier::validate()
364 if ( m_pImpl->m_bThrowException )
365 throw ucb::ResultSetException();
368 bool ResultSetDataSupplier::queryNamesOfChildren()
370 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
372 if ( m_pImpl->m_pNamesOfChildren == nullptr )
374 std::unique_ptr<uno::Sequence< OUString >> pNamesOfChildren(
375 new uno::Sequence< OUString >() );
377 if ( !m_pImpl->m_xContent->getContentProvider()->queryNamesOfChildren(
378 m_pImpl->m_xContent->getIdentifier()->getContentIdentifier(),
379 *pNamesOfChildren ) )
381 OSL_FAIL( "Got no list of children!" );
382 m_pImpl->m_bThrowException = true;
383 return false;
385 else
387 m_pImpl->m_pNamesOfChildren = std::move( pNamesOfChildren );
390 return true;
393 OUString
394 ResultSetDataSupplier::assembleChildURL( std::u16string_view aName )
396 OUString aContURL
397 = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
398 OUString aURL( aContURL );
400 sal_Int32 nUrlEnd = aURL.lastIndexOf( '/' );
401 if ( nUrlEnd != aURL.getLength() - 1 )
402 aURL += "/";
404 aURL += aName;
405 return aURL;
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */