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