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