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>
34 #include "tdoc_datasupplier.hxx"
35 #include "tdoc_content.hxx"
37 using namespace com::sun::star
;
38 using namespace tdoc_ucp
;
44 // struct ResultListEntry.
48 struct ResultListEntry
51 uno::Reference
< ucb::XContentIdentifier
> xId
;
52 uno::Reference
< ucb::XContent
> xContent
;
53 uno::Reference
< sdbc::XRow
> xRow
;
55 explicit ResultListEntry( const OUString
& rURL
) : aURL( rURL
) {}
60 // struct DataSupplier_Impl.
63 struct DataSupplier_Impl
66 std::vector
< ResultListEntry
> m_aResults
;
67 rtl::Reference
< Content
> m_xContent
;
68 uno::Reference
< uno::XComponentContext
> m_xContext
;
69 std::unique_ptr
<uno::Sequence
< OUString
> > m_pNamesOfChildren
;
71 bool m_bThrowException
;
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 )
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
) )
93 ResultSetDataSupplier::~ResultSetDataSupplier()
99 ResultSetDataSupplier::queryContentIdentifierString( sal_uInt32 nIndex
)
101 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
103 if ( nIndex
< m_pImpl
->m_aResults
.size() )
105 OUString aId
= m_pImpl
->m_aResults
[ nIndex
].aURL
;
106 if ( !aId
.isEmpty() )
113 if ( getResult( nIndex
) )
115 // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
116 return m_pImpl
->m_aResults
[ nIndex
].aURL
;
122 uno::Reference
< ucb::XContentIdentifier
>
123 ResultSetDataSupplier::queryContentIdentifier( sal_uInt32 nIndex
)
125 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
127 if ( nIndex
< m_pImpl
->m_aResults
.size() )
129 uno::Reference
< ucb::XContentIdentifier
> xId
130 = m_pImpl
->m_aResults
[ nIndex
].xId
;
138 OUString aId
= queryContentIdentifierString( nIndex
);
139 if ( !aId
.isEmpty() )
141 uno::Reference
< ucb::XContentIdentifier
> xId
142 = new ::ucbhelper::ContentIdentifier( aId
);
143 m_pImpl
->m_aResults
[ nIndex
].xId
= xId
;
146 return uno::Reference
< ucb::XContentIdentifier
>();
150 uno::Reference
< ucb::XContent
>
151 ResultSetDataSupplier::queryContent( sal_uInt32 nIndex
)
153 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
155 if ( nIndex
< m_pImpl
->m_aResults
.size() )
157 uno::Reference
< ucb::XContent
> xContent
158 = m_pImpl
->m_aResults
[ nIndex
].xContent
;
166 uno::Reference
< ucb::XContentIdentifier
> xId
167 = queryContentIdentifier( nIndex
);
172 uno::Reference
< ucb::XContent
> xContent
173 = m_pImpl
->m_xContent
->getProvider()->queryContent( xId
);
174 m_pImpl
->m_aResults
[ nIndex
].xContent
= xContent
;
178 catch ( ucb::IllegalIdentifierException
const & )
182 return uno::Reference
< ucb::XContent
>();
186 bool ResultSetDataSupplier::getResult( sal_uInt32 nIndex
)
188 osl::ClearableGuard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
190 if ( m_pImpl
->m_aResults
.size() > nIndex
)
192 // Result already present.
196 // Result not (yet) present.
198 if ( m_pImpl
->m_bCountFinal
)
201 // Try to obtain result...
203 sal_uInt32 nOldCount
= m_pImpl
->m_aResults
.size();
206 if ( queryNamesOfChildren() )
208 for ( sal_uInt32 n
= nOldCount
;
209 n
< sal::static_int_cast
<sal_uInt32
>(
210 m_pImpl
->m_pNamesOfChildren
->getLength());
213 const OUString
& rName
214 = m_pImpl
->m_pNamesOfChildren
->getConstArray()[ n
];
216 if ( rName
.isEmpty() )
218 OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
222 // Assemble URL for child.
223 OUString aURL
= assembleChildURL( rName
);
225 m_pImpl
->m_aResults
.emplace_back( aURL
);
237 m_pImpl
->m_bCountFinal
= true;
239 rtl::Reference
< ::ucbhelper::ResultSet
> xResultSet
= getResultSet();
240 if ( xResultSet
.is() )
245 if ( nOldCount
< m_pImpl
->m_aResults
.size() )
246 xResultSet
->rowCountChanged( nOldCount
, m_pImpl
->m_aResults
.size() );
248 if ( m_pImpl
->m_bCountFinal
)
249 xResultSet
->rowCountFinal();
256 sal_uInt32
ResultSetDataSupplier::totalCount()
258 osl::ClearableGuard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
260 if ( m_pImpl
->m_bCountFinal
)
261 return m_pImpl
->m_aResults
.size();
263 sal_uInt32 nOldCount
= m_pImpl
->m_aResults
.size();
265 if ( queryNamesOfChildren() )
267 for ( sal_uInt32 n
= nOldCount
;
268 n
< sal::static_int_cast
<sal_uInt32
>(
269 m_pImpl
->m_pNamesOfChildren
->getLength());
272 const OUString
& rName
273 = m_pImpl
->m_pNamesOfChildren
->getConstArray()[ n
];
275 if ( rName
.isEmpty() )
277 OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
281 // Assemble URL for child.
282 OUString aURL
= assembleChildURL( rName
);
284 m_pImpl
->m_aResults
.emplace_back( aURL
);
288 m_pImpl
->m_bCountFinal
= true;
290 rtl::Reference
< ::ucbhelper::ResultSet
> xResultSet
= getResultSet();
291 if ( xResultSet
.is() )
296 if ( nOldCount
< m_pImpl
->m_aResults
.size() )
297 xResultSet
->rowCountChanged( nOldCount
, m_pImpl
->m_aResults
.size() );
299 xResultSet
->rowCountFinal();
302 return m_pImpl
->m_aResults
.size();
306 sal_uInt32
ResultSetDataSupplier::currentCount()
308 return m_pImpl
->m_aResults
.size();
312 bool ResultSetDataSupplier::isCountFinal()
314 return m_pImpl
->m_bCountFinal
;
318 uno::Reference
< sdbc::XRow
>
319 ResultSetDataSupplier::queryPropertyValues( sal_uInt32 nIndex
)
321 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
323 if ( nIndex
< m_pImpl
->m_aResults
.size() )
325 uno::Reference
< sdbc::XRow
> xRow
= m_pImpl
->m_aResults
[ nIndex
].xRow
;
333 if ( getResult( nIndex
) )
335 uno::Reference
< sdbc::XRow
> xRow
= Content::getPropertyValues(
337 getResultSet()->getProperties(),
338 m_pImpl
->m_xContent
->getContentProvider().get(),
339 queryContentIdentifierString( nIndex
) );
340 m_pImpl
->m_aResults
[ nIndex
].xRow
= xRow
;
344 return uno::Reference
< sdbc::XRow
>();
348 void ResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex
)
350 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
352 if ( nIndex
< m_pImpl
->m_aResults
.size() )
353 m_pImpl
->m_aResults
[ nIndex
].xRow
.clear();
357 void ResultSetDataSupplier::close()
362 void ResultSetDataSupplier::validate()
364 if ( m_pImpl
->m_bThrowException
)
365 throw ucb::ResultSetException();
368 bool ResultSetDataSupplier::queryNamesOfChildren()
370 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
372 if ( m_pImpl
->m_pNamesOfChildren
== nullptr )
374 std::unique_ptr
<uno::Sequence
< OUString
>> pNamesOfChildren(
375 new uno::Sequence
< OUString
>() );
377 if ( !m_pImpl
->m_xContent
->getContentProvider()->queryNamesOfChildren(
378 m_pImpl
->m_xContent
->getIdentifier()->getContentIdentifier(),
379 *pNamesOfChildren
) )
381 OSL_FAIL( "Got no list of children!" );
382 m_pImpl
->m_bThrowException
= true;
387 m_pImpl
->m_pNamesOfChildren
= std::move( pNamesOfChildren
);
394 ResultSetDataSupplier::assembleChildURL( std::u16string_view aName
)
397 = m_pImpl
->m_xContent
->getIdentifier()->getContentIdentifier();
398 OUString
aURL( aContURL
);
400 sal_Int32 nUrlEnd
= aURL
.lastIndexOf( '/' );
401 if ( nUrlEnd
!= aURL
.getLength() - 1 )
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */