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