Update git submodules
[LibreOffice.git] / ucb / source / ucp / package / pkgdatasupplier.cxx
bloba1660b41d6c9e635b240cdd803dd8312e99e86b5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 /**************************************************************************
22 TODO
23 **************************************************************************
25 *************************************************************************/
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>
31 #include <ucbhelper/contentidentifier.hxx>
32 #include <ucbhelper/providerhelper.hxx>
33 #include <utility>
34 #include "pkgdatasupplier.hxx"
35 #include "pkgcontent.hxx"
36 #include "pkgprovider.hxx"
38 #include "../inc/urihelper.hxx"
40 using namespace com::sun::star;
41 using namespace package_ucp;
43 // DataSupplier Implementation.
46 DataSupplier::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 )
56 // virtual
57 DataSupplier::~DataSupplier()
62 // virtual
63 OUString DataSupplier::queryContentIdentifierString( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
65 std::unique_lock aGuard( m_aMutex );
66 return queryContentIdentifierStringImpl(rResultSetGuard, aGuard, nIndex);
69 OUString DataSupplier::queryContentIdentifierStringImpl( std::unique_lock<std::mutex>& rResultSetGuard, std::unique_lock<std::mutex>& rGuard, sal_uInt32 nIndex )
71 if ( nIndex < m_aResults.size() )
73 OUString aId = m_aResults[ nIndex ].aURL;
74 if ( !aId.isEmpty() )
76 // Already cached.
77 return aId;
81 if ( getResultImpl( rResultSetGuard, rGuard, nIndex ) )
83 // Note: getResult fills m_aResults[ nIndex ].aURL.
84 return m_aResults[ nIndex ].aURL;
86 return OUString();
90 // virtual
91 uno::Reference< ucb::XContentIdentifier >
92 DataSupplier::queryContentIdentifier( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
94 std::unique_lock aGuard( m_aMutex );
95 return queryContentIdentifierImpl(rResultSetGuard, aGuard, nIndex);
98 uno::Reference< ucb::XContentIdentifier >
99 DataSupplier::queryContentIdentifierImpl( std::unique_lock<std::mutex>& rResultSetGuard, std::unique_lock<std::mutex>& rGuard, sal_uInt32 nIndex )
101 if ( nIndex < m_aResults.size() )
103 uno::Reference< ucb::XContentIdentifier >& xId
104 = m_aResults[ nIndex ].xId;
105 if ( xId.is() )
107 // Already cached.
108 return xId;
112 OUString aId = queryContentIdentifierStringImpl( rResultSetGuard, rGuard, nIndex );
113 if ( !aId.isEmpty() )
115 uno::Reference< ucb::XContentIdentifier > xId
116 = new ::ucbhelper::ContentIdentifier( aId );
117 m_aResults[ nIndex ].xId = xId;
118 return xId;
120 return uno::Reference< ucb::XContentIdentifier >();
124 // virtual
125 uno::Reference< ucb::XContent > DataSupplier::queryContent(
126 std::unique_lock<std::mutex>& rResultSetGuard,
127 sal_uInt32 nIndex )
129 std::unique_lock aGuard( m_aMutex );
131 if ( nIndex < m_aResults.size() )
133 uno::Reference< ucb::XContent >& xContent
134 = m_aResults[ nIndex ].xContent;
135 if ( xContent.is() )
137 // Already cached.
138 return xContent;
142 uno::Reference< ucb::XContentIdentifier > xId
143 = queryContentIdentifierImpl( rResultSetGuard, aGuard, nIndex );
144 if ( xId.is() )
148 uno::Reference< ucb::XContent > xContent
149 = m_xContent->getProvider()->queryContent( xId );
150 m_aResults[ nIndex ].xContent = xContent;
151 return xContent;
154 catch ( ucb::IllegalIdentifierException const & )
158 return uno::Reference< ucb::XContent >();
162 // virtual
163 bool DataSupplier::getResult( std::unique_lock<std::mutex>& rResultSetGuard, sal_uInt32 nIndex )
165 std::unique_lock aGuard( m_aMutex );
166 return getResultImpl(rResultSetGuard, aGuard, nIndex);
169 bool DataSupplier::getResultImpl( std::unique_lock<std::mutex>& rResultSetGuard, std::unique_lock<std::mutex>& rGuard, sal_uInt32 nIndex )
171 if ( m_aResults.size() > nIndex )
173 // Result already present.
174 return true;
177 // Result not (yet) present.
179 if ( m_bCountFinal )
180 return false;
182 // Try to obtain result...
184 sal_uInt32 nOldCount = m_aResults.size();
185 bool bFound = false;
186 sal_uInt32 nPos = nOldCount;
188 while ( m_xFolderEnum->hasMoreElements() )
192 uno::Reference< container::XNamed > xNamed;
193 m_xFolderEnum->nextElement() >>= xNamed;
195 if ( !xNamed.is() )
197 OSL_FAIL( "DataSupplier::getResult - Got no XNamed!" );
198 break;
201 OUString aName = xNamed->getName();
203 if ( aName.isEmpty() )
205 OSL_FAIL( "DataSupplier::getResult - Empty name!" );
206 break;
209 // Assemble URL for child.
210 OUString aURL = assembleChildURL( aName );
212 m_aResults.emplace_back(aURL);
214 if ( nPos == nIndex )
216 // Result obtained.
217 bFound = true;
218 break;
221 nPos++;
223 catch ( container::NoSuchElementException const & )
225 m_bThrowException = true;
226 break;
228 catch ( lang::WrappedTargetException const & )
230 m_bThrowException = true;
231 break;
235 if ( !bFound )
236 m_bCountFinal = true;
238 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet();
239 if ( xResultSet.is() )
241 // Callbacks follow!
242 rGuard.unlock();
244 if ( nOldCount < m_aResults.size() )
245 xResultSet->rowCountChanged(rResultSetGuard,
246 nOldCount, m_aResults.size() );
248 if ( m_bCountFinal )
249 xResultSet->rowCountFinal(rResultSetGuard);
251 rGuard.lock();
254 return bFound;
258 // virtual
259 sal_uInt32 DataSupplier::totalCount(std::unique_lock<std::mutex>& rResultSetGuard)
261 std::unique_lock aGuard( m_aMutex );
263 if ( m_bCountFinal )
264 return m_aResults.size();
266 sal_uInt32 nOldCount = m_aResults.size();
268 while ( m_xFolderEnum->hasMoreElements() )
272 uno::Reference< container::XNamed > xNamed;
273 m_xFolderEnum->nextElement() >>= xNamed;
275 if ( !xNamed.is() )
277 OSL_FAIL( "DataSupplier::getResult - Got no XNamed!" );
278 break;
281 OUString aName = xNamed->getName();
283 if ( aName.isEmpty() )
285 OSL_FAIL( "DataSupplier::getResult - Empty name!" );
286 break;
289 // Assemble URL for child.
290 OUString aURL = assembleChildURL( aName );
292 m_aResults.emplace_back(aURL);
294 catch ( container::NoSuchElementException const & )
296 m_bThrowException = true;
297 break;
299 catch ( lang::WrappedTargetException const & )
301 m_bThrowException = true;
302 break;
306 m_bCountFinal = true;
308 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet();
309 if ( xResultSet.is() )
311 // Callbacks follow!
312 aGuard.unlock();
314 if ( nOldCount < m_aResults.size() )
315 xResultSet->rowCountChanged(rResultSetGuard,
316 nOldCount, m_aResults.size() );
318 xResultSet->rowCountFinal(rResultSetGuard);
321 return m_aResults.size();
325 // virtual
326 sal_uInt32 DataSupplier::currentCount()
328 return m_aResults.size();
332 // virtual
333 bool DataSupplier::isCountFinal()
335 return m_bCountFinal;
339 // virtual
340 uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues(
341 std::unique_lock<std::mutex>& rResultSetGuard,
342 sal_uInt32 nIndex )
344 std::unique_lock aGuard( m_aMutex );
346 if ( nIndex < m_aResults.size() )
348 uno::Reference< sdbc::XRow >& xRow = m_aResults[ nIndex ].xRow;
349 if ( xRow.is() )
351 // Already cached.
352 return xRow;
356 if ( getResultImpl( rResultSetGuard, aGuard, nIndex ) )
358 uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
359 m_xContext,
360 getResultSet()->getProperties(),
361 static_cast< ContentProvider * >(
362 m_xContent->getProvider().get() ),
363 queryContentIdentifierStringImpl( rResultSetGuard, aGuard, nIndex ) );
364 m_aResults[ nIndex ].xRow = xRow;
365 return xRow;
368 return uno::Reference< sdbc::XRow >();
372 // virtual
373 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
375 std::unique_lock aGuard( m_aMutex );
377 if ( nIndex < m_aResults.size() )
378 m_aResults[ nIndex ].xRow.clear();
382 // virtual
383 void DataSupplier::close()
388 // virtual
389 void DataSupplier::validate()
391 if ( m_bThrowException )
392 throw ucb::ResultSetException();
396 OUString DataSupplier::assembleChildURL( const OUString& aName )
398 OUString aURL;
399 OUString aContURL
400 = m_xContent->getIdentifier()->getContentIdentifier();
401 sal_Int32 nParam = aContURL.indexOf( '?' );
402 if ( nParam >= 0 )
404 aURL = aContURL.copy( 0, nParam );
406 sal_Int32 nPackageUrlEnd = aURL.lastIndexOf( '/' );
407 if ( nPackageUrlEnd != aURL.getLength() - 1 )
408 aURL += "/";
410 aURL += ::ucb_impl::urihelper::encodeSegment( aName ) +
411 aContURL.subView( nParam );
413 else
415 aURL = aContURL;
417 sal_Int32 nPackageUrlEnd = aURL.lastIndexOf( '/' );
418 if ( nPackageUrlEnd != aURL.getLength() - 1 )
419 aURL += "/";
421 aURL += ::ucb_impl::urihelper::encodeSegment( aName );
423 return aURL;
427 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */