1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 /**************************************************************************
23 **************************************************************************
25 *************************************************************************/
29 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
30 #include <com/sun/star/ucb/ResultSetException.hpp>
31 #include <osl/diagnose.h>
32 #include <ucbhelper/contentidentifier.hxx>
35 #include "tdoc_datasupplier.hxx"
36 #include "tdoc_content.hxx"
38 using namespace com::sun::star
;
39 using namespace tdoc_ucp
;
45 // struct ResultListEntry.
52 // struct DataSupplier_Impl.
57 // DataSupplier Implementation.
58 ResultSetDataSupplier::ResultSetDataSupplier(
59 uno::Reference
< uno::XComponentContext
> xContext
,
60 rtl::Reference
< Content
> xContent
)
61 : m_xContent(std::move( xContent
)), m_xContext(std::move( xContext
)),
62 m_bCountFinal( false ), m_bThrowException( false )
67 ResultSetDataSupplier::~ResultSetDataSupplier()
73 ResultSetDataSupplier::queryContentIdentifierString( std::unique_lock
<std::mutex
>& rResultSetGuard
, sal_uInt32 nIndex
)
75 std::unique_lock
aGuard( m_aMutex
);
76 return queryContentIdentifierStringImpl(rResultSetGuard
, aGuard
, nIndex
);
80 ResultSetDataSupplier::queryContentIdentifierStringImpl( std::unique_lock
<std::mutex
>& rResultSetGuard
, std::unique_lock
<std::mutex
>& rGuard
, sal_uInt32 nIndex
)
82 if ( nIndex
< m_aResults
.size() )
84 OUString aId
= m_aResults
[ nIndex
].aURL
;
92 if ( getResultImpl(rResultSetGuard
, rGuard
, nIndex
) )
94 // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
95 return m_aResults
[ nIndex
].aURL
;
101 uno::Reference
< ucb::XContentIdentifier
>
102 ResultSetDataSupplier::queryContentIdentifier( std::unique_lock
<std::mutex
>& rResultSetGuard
, sal_uInt32 nIndex
)
104 std::unique_lock
aGuard( m_aMutex
);
105 return queryContentIdentifierImpl(rResultSetGuard
, aGuard
, nIndex
);
108 uno::Reference
< ucb::XContentIdentifier
>
109 ResultSetDataSupplier::queryContentIdentifierImpl( std::unique_lock
<std::mutex
>& rResultSetGuard
, std::unique_lock
<std::mutex
>& rGuard
, sal_uInt32 nIndex
)
111 if ( nIndex
< m_aResults
.size() )
113 uno::Reference
< ucb::XContentIdentifier
> xId
114 = m_aResults
[ nIndex
].xId
;
122 OUString aId
= queryContentIdentifierStringImpl( rResultSetGuard
, rGuard
, nIndex
);
123 if ( !aId
.isEmpty() )
125 uno::Reference
< ucb::XContentIdentifier
> xId
126 = new ::ucbhelper::ContentIdentifier( aId
);
127 m_aResults
[ nIndex
].xId
= xId
;
130 return uno::Reference
< ucb::XContentIdentifier
>();
134 uno::Reference
< ucb::XContent
>
135 ResultSetDataSupplier::queryContent( std::unique_lock
<std::mutex
>& rResultSetGuard
, sal_uInt32 nIndex
)
137 std::unique_lock
aGuard( m_aMutex
);
139 if ( nIndex
< m_aResults
.size() )
141 uno::Reference
< ucb::XContent
> xContent
142 = m_aResults
[ nIndex
].xContent
;
150 uno::Reference
< ucb::XContentIdentifier
> xId
151 = queryContentIdentifierImpl( rResultSetGuard
, aGuard
, nIndex
);
156 uno::Reference
< ucb::XContent
> xContent
157 = m_xContent
->getProvider()->queryContent( xId
);
158 m_aResults
[ nIndex
].xContent
= xContent
;
162 catch ( ucb::IllegalIdentifierException
const & )
166 return uno::Reference
< ucb::XContent
>();
170 bool ResultSetDataSupplier::getResult( std::unique_lock
<std::mutex
>& rResultSetGuard
, sal_uInt32 nIndex
)
172 std::unique_lock
aGuard( m_aMutex
);
173 return getResultImpl(rResultSetGuard
, aGuard
, nIndex
);
176 bool ResultSetDataSupplier::getResultImpl( std::unique_lock
<std::mutex
>& rResultSetGuard
, std::unique_lock
<std::mutex
>& rGuard
, sal_uInt32 nIndex
)
178 if ( m_aResults
.size() > nIndex
)
180 // Result already present.
184 // Result not (yet) present.
189 // Try to obtain result...
191 sal_uInt32 nOldCount
= m_aResults
.size();
194 if ( queryNamesOfChildren(rGuard
) )
196 for ( sal_uInt32 n
= nOldCount
;
197 n
< sal::static_int_cast
<sal_uInt32
>(
198 m_xNamesOfChildren
->getLength());
201 const OUString
& rName
202 = m_xNamesOfChildren
->getConstArray()[ n
];
204 if ( rName
.isEmpty() )
206 OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
210 // Assemble URL for child.
211 OUString aURL
= assembleChildURL( rName
);
213 m_aResults
.emplace_back( aURL
);
225 m_bCountFinal
= true;
227 rtl::Reference
< ::ucbhelper::ResultSet
> xResultSet
= getResultSet();
228 if ( xResultSet
.is() )
233 if ( nOldCount
< m_aResults
.size() )
234 xResultSet
->rowCountChanged( rResultSetGuard
, nOldCount
, m_aResults
.size() );
237 xResultSet
->rowCountFinal(rResultSetGuard
);
246 sal_uInt32
ResultSetDataSupplier::totalCount(std::unique_lock
<std::mutex
>& rResultSetGuard
)
248 std::unique_lock
aGuard( m_aMutex
);
251 return m_aResults
.size();
253 sal_uInt32 nOldCount
= m_aResults
.size();
255 if ( queryNamesOfChildren(aGuard
) )
257 for ( sal_uInt32 n
= nOldCount
;
258 n
< sal::static_int_cast
<sal_uInt32
>(
259 m_xNamesOfChildren
->getLength());
262 const OUString
& rName
263 = m_xNamesOfChildren
->getConstArray()[ n
];
265 if ( rName
.isEmpty() )
267 OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
271 // Assemble URL for child.
272 OUString aURL
= assembleChildURL( rName
);
274 m_aResults
.emplace_back( aURL
);
278 m_bCountFinal
= true;
280 rtl::Reference
< ::ucbhelper::ResultSet
> xResultSet
= getResultSet();
281 if ( xResultSet
.is() )
286 if ( nOldCount
< m_aResults
.size() )
287 xResultSet
->rowCountChanged( rResultSetGuard
, nOldCount
, m_aResults
.size() );
289 xResultSet
->rowCountFinal(rResultSetGuard
);
292 return m_aResults
.size();
296 sal_uInt32
ResultSetDataSupplier::currentCount()
298 return m_aResults
.size();
302 bool ResultSetDataSupplier::isCountFinal()
304 return m_bCountFinal
;
308 uno::Reference
< sdbc::XRow
>
309 ResultSetDataSupplier::queryPropertyValues( std::unique_lock
<std::mutex
>& rResultSetGuard
, sal_uInt32 nIndex
)
311 std::unique_lock
aGuard( m_aMutex
);
313 if ( nIndex
< m_aResults
.size() )
315 uno::Reference
< sdbc::XRow
> xRow
= m_aResults
[ nIndex
].xRow
;
323 if ( getResultImpl( rResultSetGuard
, aGuard
, nIndex
) )
325 uno::Reference
< sdbc::XRow
> xRow
= Content::getPropertyValues(
327 getResultSet()->getProperties(),
328 m_xContent
->getContentProvider().get(),
329 queryContentIdentifierStringImpl( rResultSetGuard
, aGuard
, nIndex
) );
330 m_aResults
[ nIndex
].xRow
= xRow
;
334 return uno::Reference
< sdbc::XRow
>();
338 void ResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex
)
340 std::unique_lock
aGuard( m_aMutex
);
342 if ( nIndex
< m_aResults
.size() )
343 m_aResults
[ nIndex
].xRow
.clear();
347 void ResultSetDataSupplier::close()
352 void ResultSetDataSupplier::validate()
354 if ( m_bThrowException
)
355 throw ucb::ResultSetException();
358 bool ResultSetDataSupplier::queryNamesOfChildren(std::unique_lock
<std::mutex
>& /*rGuard*/)
360 if ( !m_xNamesOfChildren
)
362 uno::Sequence
< OUString
> aNamesOfChildren
;
364 if ( !m_xContent
->getContentProvider()->queryNamesOfChildren(
365 m_xContent
->getIdentifier()->getContentIdentifier(),
368 OSL_FAIL( "Got no list of children!" );
369 m_bThrowException
= true;
374 m_xNamesOfChildren
= std::move( aNamesOfChildren
);
381 ResultSetDataSupplier::assembleChildURL( std::u16string_view aName
)
384 = m_xContent
->getIdentifier()->getContentIdentifier();
386 sal_Int32 nUrlEnd
= aURL
.lastIndexOf( '/' );
387 if ( nUrlEnd
!= aURL
.getLength() - 1 )
394 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */