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