LibreOffice Module ucb (master)  1
tdoc_datasupplier.cxx
Go to the documentation of this file.
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 <optional>
28 #include <vector>
29 
30 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
31 #include <com/sun/star/ucb/ResultSetException.hpp>
32 #include <osl/diagnose.h>
34 
35 #include "tdoc_datasupplier.hxx"
36 #include "tdoc_content.hxx"
37 
38 using namespace com::sun::star;
39 using namespace tdoc_ucp;
40 
41 namespace tdoc_ucp
42 {
43 
44 
45 // struct ResultListEntry.
46 
47 namespace {
48 
49 
50 }
51 
52 // struct DataSupplier_Impl.
53 
54 
55 }
56 
57 // DataSupplier Implementation.
58 ResultSetDataSupplier::ResultSetDataSupplier(
59  const uno::Reference< uno::XComponentContext >& rxContext,
60  const rtl::Reference< Content >& rContent )
61 : m_xContent( rContent ), m_xContext( rxContext ),
62  m_bCountFinal( false ), m_bThrowException( false )
63 {
64 }
65 
66 // virtual
67 ResultSetDataSupplier::~ResultSetDataSupplier()
68 {
69 }
70 
71 // virtual
72 OUString
74 {
75  osl::Guard< osl::Mutex > aGuard( m_aMutex );
76 
77  if ( nIndex < m_aResults.size() )
78  {
79  OUString aId = m_aResults[ nIndex ].aURL;
80  if ( !aId.isEmpty() )
81  {
82  // Already cached.
83  return aId;
84  }
85  }
86 
87  if ( getResult( nIndex ) )
88  {
89  // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
90  return m_aResults[ nIndex ].aURL;
91  }
92  return OUString();
93 }
94 
95 // virtual
96 uno::Reference< ucb::XContentIdentifier >
98 {
99  osl::Guard< osl::Mutex > aGuard( m_aMutex );
100 
101  if ( nIndex < m_aResults.size() )
102  {
103  uno::Reference< ucb::XContentIdentifier > xId
104  = m_aResults[ nIndex ].xId;
105  if ( xId.is() )
106  {
107  // Already cached.
108  return xId;
109  }
110  }
111 
112  OUString aId = queryContentIdentifierString( nIndex );
113  if ( !aId.isEmpty() )
114  {
115  uno::Reference< ucb::XContentIdentifier > xId
116  = new ::ucbhelper::ContentIdentifier( aId );
117  m_aResults[ nIndex ].xId = xId;
118  return xId;
119  }
120  return uno::Reference< ucb::XContentIdentifier >();
121 }
122 
123 // virtual
124 uno::Reference< ucb::XContent >
126 {
127  osl::Guard< osl::Mutex > aGuard( m_aMutex );
128 
129  if ( nIndex < m_aResults.size() )
130  {
131  uno::Reference< ucb::XContent > xContent
132  = m_aResults[ nIndex ].xContent;
133  if ( xContent.is() )
134  {
135  // Already cached.
136  return xContent;
137  }
138  }
139 
140  uno::Reference< ucb::XContentIdentifier > xId
141  = queryContentIdentifier( nIndex );
142  if ( xId.is() )
143  {
144  try
145  {
146  uno::Reference< ucb::XContent > xContent
147  = m_xContent->getProvider()->queryContent( xId );
148  m_aResults[ nIndex ].xContent = xContent;
149  return xContent;
150 
151  }
152  catch ( ucb::IllegalIdentifierException const & )
153  {
154  }
155  }
156  return uno::Reference< ucb::XContent >();
157 }
158 
159 // virtual
160 bool ResultSetDataSupplier::getResult( sal_uInt32 nIndex )
161 {
162  osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
163 
164  if ( m_aResults.size() > nIndex )
165  {
166  // Result already present.
167  return true;
168  }
169 
170  // Result not (yet) present.
171 
172  if ( m_bCountFinal )
173  return false;
174 
175  // Try to obtain result...
176 
177  sal_uInt32 nOldCount = m_aResults.size();
178  bool bFound = false;
179 
180  if ( queryNamesOfChildren() )
181  {
182  for ( sal_uInt32 n = nOldCount;
183  n < sal::static_int_cast<sal_uInt32>(
184  m_xNamesOfChildren->getLength());
185  ++n )
186  {
187  const OUString & rName
188  = m_xNamesOfChildren->getConstArray()[ n ];
189 
190  if ( rName.isEmpty() )
191  {
192  OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
193  break;
194  }
195 
196  // Assemble URL for child.
197  OUString aURL = assembleChildURL( rName );
198 
199  m_aResults.emplace_back( aURL );
200 
201  if ( n == nIndex )
202  {
203  // Result obtained.
204  bFound = true;
205  break;
206  }
207  }
208  }
209 
210  if ( !bFound )
211  m_bCountFinal = true;
212 
214  if ( xResultSet.is() )
215  {
216  // Callbacks follow!
217  aGuard.clear();
218 
219  if ( nOldCount < m_aResults.size() )
220  xResultSet->rowCountChanged( nOldCount, m_aResults.size() );
221 
222  if ( m_bCountFinal )
223  xResultSet->rowCountFinal();
224  }
225 
226  return bFound;
227 }
228 
229 // virtual
231 {
232  osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
233 
234  if ( m_bCountFinal )
235  return m_aResults.size();
236 
237  sal_uInt32 nOldCount = m_aResults.size();
238 
239  if ( queryNamesOfChildren() )
240  {
241  for ( sal_uInt32 n = nOldCount;
242  n < sal::static_int_cast<sal_uInt32>(
243  m_xNamesOfChildren->getLength());
244  ++n )
245  {
246  const OUString & rName
247  = m_xNamesOfChildren->getConstArray()[ n ];
248 
249  if ( rName.isEmpty() )
250  {
251  OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
252  break;
253  }
254 
255  // Assemble URL for child.
256  OUString aURL = assembleChildURL( rName );
257 
258  m_aResults.emplace_back( aURL );
259  }
260  }
261 
262  m_bCountFinal = true;
263 
265  if ( xResultSet.is() )
266  {
267  // Callbacks follow!
268  aGuard.clear();
269 
270  if ( nOldCount < m_aResults.size() )
271  xResultSet->rowCountChanged( nOldCount, m_aResults.size() );
272 
273  xResultSet->rowCountFinal();
274  }
275 
276  return m_aResults.size();
277 }
278 
279 // virtual
281 {
282  return m_aResults.size();
283 }
284 
285 // virtual
287 {
288  return m_bCountFinal;
289 }
290 
291 // virtual
292 uno::Reference< sdbc::XRow >
294 {
295  osl::Guard< osl::Mutex > aGuard( m_aMutex );
296 
297  if ( nIndex < m_aResults.size() )
298  {
299  uno::Reference< sdbc::XRow > xRow = m_aResults[ nIndex ].xRow;
300  if ( xRow.is() )
301  {
302  // Already cached.
303  return xRow;
304  }
305  }
306 
307  if ( getResult( nIndex ) )
308  {
309  uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
310  m_xContext,
311  getResultSet()->getProperties(),
312  m_xContent->getContentProvider().get(),
313  queryContentIdentifierString( nIndex ) );
314  m_aResults[ nIndex ].xRow = xRow;
315  return xRow;
316  }
317 
318  return uno::Reference< sdbc::XRow >();
319 }
320 
321 // virtual
323 {
324  osl::Guard< osl::Mutex > aGuard( m_aMutex );
325 
326  if ( nIndex < m_aResults.size() )
327  m_aResults[ nIndex ].xRow.clear();
328 }
329 
330 // virtual
332 {
333 }
334 
335 // virtual
337 {
338  if ( m_bThrowException )
339  throw ucb::ResultSetException();
340 }
341 
343 {
344  osl::Guard< osl::Mutex > aGuard( m_aMutex );
345 
346  if ( !m_xNamesOfChildren )
347  {
348  uno::Sequence< OUString > aNamesOfChildren;
349 
350  if ( !m_xContent->getContentProvider()->queryNamesOfChildren(
351  m_xContent->getIdentifier()->getContentIdentifier(),
352  aNamesOfChildren ) )
353  {
354  OSL_FAIL( "Got no list of children!" );
355  m_bThrowException = true;
356  return false;
357  }
358  else
359  {
360  m_xNamesOfChildren = std::move( aNamesOfChildren );
361  }
362  }
363  return true;
364 }
365 
366 OUString
367 ResultSetDataSupplier::assembleChildURL( std::u16string_view aName )
368 {
369  OUString aContURL
370  = m_xContent->getIdentifier()->getContentIdentifier();
371  OUString aURL( aContURL );
372 
373  sal_Int32 nUrlEnd = aURL.lastIndexOf( '/' );
374  if ( nUrlEnd != aURL.getLength() - 1 )
375  aURL += "/";
376 
377  aURL += aName;
378  return aURL;
379 }
380 
381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
rtl::Reference< Content > m_xContent
virtual css::uno::Reference< css::ucb::XContentIdentifier > queryContentIdentifier(sal_uInt32 nIndex) override
sal_Int64 n
std::vector< ResultListEntry > m_aResults
OUString aId
Reference< XRow > xRow
css::uno::Reference< css::sdbc::XRow > getPropertyValues(const css::uno::Sequence< css::beans::Property > &rProperties)
std::optional< css::uno::Sequence< OUString > > m_xNamesOfChildren
uno::Reference< ucb::XContent > m_xContent
virtual bool getResult(sal_uInt32 nIndex) override
virtual css::uno::Reference< css::sdbc::XRow > queryPropertyValues(sal_uInt32 nIndex) override
OUString aURL
OUString assembleChildURL(std::u16string_view aName)
rtl::Reference< ResultSet > getResultSet() const
virtual bool isCountFinal() override
virtual void validate() override
virtual css::uno::Reference< css::ucb::XContent > queryContent(sal_uInt32 nIndex) override
virtual sal_uInt32 totalCount() override
virtual void releasePropertyValues(sal_uInt32 nIndex) override
css::uno::Reference< css::uno::XComponentContext > m_xContext
virtual OUString queryContentIdentifierString(sal_uInt32 nIndex) override
virtual sal_uInt32 currentCount() override
Reference< XContentIdentifier > xId
uno::Reference< ucb::XContent > xContent
Reference< XComponentContext > m_xContext