Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / ucb / source / ucp / hierarchy / hierarchydatasupplier.cxx
blobc31eb075227c8129dbdcc44d43737c6899b0414d
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 <vector>
29 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
30 #include <com/sun/star/ucb/OpenMode.hpp>
31 #include <ucbhelper/contentidentifier.hxx>
32 #include "hierarchydatasupplier.hxx"
33 #include "hierarchyprovider.hxx"
34 #include "hierarchycontent.hxx"
36 using namespace com::sun::star;
37 using namespace hierarchy_ucp;
39 namespace hierarchy_ucp
43 // struct ResultListEntry.
46 struct ResultListEntry
48 OUString aId;
49 uno::Reference< ucb::XContentIdentifier > xId;
50 uno::Reference< ucb::XContent > xContent;
51 uno::Reference< sdbc::XRow > xRow;
52 HierarchyEntryData const aData;
54 explicit ResultListEntry( const HierarchyEntryData& rEntry ) : aData( rEntry ) {}
58 // ResultList.
61 typedef std::vector< std::unique_ptr<ResultListEntry> > ResultList;
64 // struct DataSupplier_Impl.
67 struct DataSupplier_Impl
69 osl::Mutex m_aMutex;
70 ResultList m_aResults;
71 rtl::Reference< HierarchyContent > m_xContent;
72 uno::Reference< uno::XComponentContext > m_xContext;
73 HierarchyEntry m_aFolder;
74 HierarchyEntry::iterator const m_aIterator;
75 sal_Int32 const m_nOpenMode;
76 bool m_bCountFinal;
78 DataSupplier_Impl(
79 const uno::Reference< uno::XComponentContext >& rxContext,
80 const rtl::Reference< HierarchyContent >& rContent,
81 sal_Int32 nOpenMode )
82 : m_xContent( rContent ), m_xContext( rxContext ),
83 m_aFolder( rxContext,
84 static_cast< HierarchyContentProvider * >(
85 rContent->getProvider().get() ),
86 rContent->getIdentifier()->getContentIdentifier() ),
87 m_nOpenMode( nOpenMode ), m_bCountFinal( false ) {}
94 // HierarchyResultSetDataSupplier Implementation.
97 HierarchyResultSetDataSupplier::HierarchyResultSetDataSupplier(
98 const uno::Reference< uno::XComponentContext >& rxContext,
99 const rtl::Reference< HierarchyContent >& rContent,
100 sal_Int32 nOpenMode )
101 : m_pImpl( new DataSupplier_Impl( rxContext, rContent, nOpenMode ) )
106 // virtual
107 HierarchyResultSetDataSupplier::~HierarchyResultSetDataSupplier()
112 // virtual
113 OUString HierarchyResultSetDataSupplier::queryContentIdentifierString(
114 sal_uInt32 nIndex )
116 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
118 if ( nIndex < m_pImpl->m_aResults.size() )
120 OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
121 if ( !aId.isEmpty() )
123 // Already cached.
124 return aId;
128 if ( getResult( nIndex ) )
130 OUString aId
131 = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
133 if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
134 aId += "/";
136 aId += m_pImpl->m_aResults[ nIndex ]->aData.getName();
138 m_pImpl->m_aResults[ nIndex ]->aId = aId;
139 return aId;
141 return OUString();
145 // virtual
146 uno::Reference< ucb::XContentIdentifier >
147 HierarchyResultSetDataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
149 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
151 if ( nIndex < m_pImpl->m_aResults.size() )
153 uno::Reference< ucb::XContentIdentifier > xId
154 = m_pImpl->m_aResults[ nIndex ]->xId;
155 if ( xId.is() )
157 // Already cached.
158 return xId;
162 OUString aId = queryContentIdentifierString( nIndex );
163 if ( !aId.isEmpty() )
165 uno::Reference< ucb::XContentIdentifier > xId
166 = new ::ucbhelper::ContentIdentifier( aId );
167 m_pImpl->m_aResults[ nIndex ]->xId = xId;
168 return xId;
170 return uno::Reference< ucb::XContentIdentifier >();
174 // virtual
175 uno::Reference< ucb::XContent >
176 HierarchyResultSetDataSupplier::queryContent( sal_uInt32 nIndex )
178 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
180 if ( nIndex < m_pImpl->m_aResults.size() )
182 uno::Reference< ucb::XContent > xContent
183 = m_pImpl->m_aResults[ nIndex ]->xContent;
184 if ( xContent.is() )
186 // Already cached.
187 return xContent;
191 uno::Reference< ucb::XContentIdentifier > xId
192 = queryContentIdentifier( nIndex );
193 if ( xId.is() )
197 uno::Reference< ucb::XContent > xContent
198 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
199 m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
200 return xContent;
203 catch ( ucb::IllegalIdentifierException const & )
207 return uno::Reference< ucb::XContent >();
211 // virtual
212 bool HierarchyResultSetDataSupplier::getResult( sal_uInt32 nIndex )
214 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
216 if ( m_pImpl->m_aResults.size() > nIndex )
218 // Result already present.
219 return true;
222 // Result not (yet) present.
224 if ( m_pImpl->m_bCountFinal )
225 return false;
227 // Try to obtain result...
229 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
230 bool bFound = false;
231 sal_uInt32 nPos = nOldCount;
233 while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
235 const HierarchyEntryData& rResult = *m_pImpl->m_aIterator;
236 if ( checkResult( rResult ) )
238 m_pImpl->m_aResults.emplace_back( new ResultListEntry( rResult ) );
240 if ( nPos == nIndex )
242 // Result obtained.
243 bFound = true;
244 break;
247 nPos++;
250 if ( !bFound )
251 m_pImpl->m_bCountFinal = true;
253 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
254 if ( xResultSet.is() )
256 // Callbacks follow!
257 aGuard.clear();
259 if ( nOldCount < m_pImpl->m_aResults.size() )
260 xResultSet->rowCountChanged(
261 nOldCount, m_pImpl->m_aResults.size() );
263 if ( m_pImpl->m_bCountFinal )
264 xResultSet->rowCountFinal();
267 return bFound;
271 // virtual
272 sal_uInt32 HierarchyResultSetDataSupplier::totalCount()
274 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
276 if ( m_pImpl->m_bCountFinal )
277 return m_pImpl->m_aResults.size();
279 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
281 while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
283 const HierarchyEntryData& rResult = *m_pImpl->m_aIterator;
284 if ( checkResult( rResult ) )
285 m_pImpl->m_aResults.emplace_back( new ResultListEntry( rResult ) );
288 m_pImpl->m_bCountFinal = true;
290 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
291 if ( xResultSet.is() )
293 // Callbacks follow!
294 aGuard.clear();
296 if ( nOldCount < m_pImpl->m_aResults.size() )
297 xResultSet->rowCountChanged(
298 nOldCount, m_pImpl->m_aResults.size() );
300 xResultSet->rowCountFinal();
303 return m_pImpl->m_aResults.size();
307 // virtual
308 sal_uInt32 HierarchyResultSetDataSupplier::currentCount()
310 return m_pImpl->m_aResults.size();
314 // virtual
315 bool HierarchyResultSetDataSupplier::isCountFinal()
317 return m_pImpl->m_bCountFinal;
321 // virtual
322 uno::Reference< sdbc::XRow >
323 HierarchyResultSetDataSupplier::queryPropertyValues( sal_uInt32 nIndex )
325 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
327 if ( nIndex < m_pImpl->m_aResults.size() )
329 uno::Reference< sdbc::XRow > xRow
330 = m_pImpl->m_aResults[ nIndex ]->xRow;
331 if ( xRow.is() )
333 // Already cached.
334 return xRow;
338 if ( getResult( nIndex ) )
340 HierarchyContentProperties aData(
341 m_pImpl->m_aResults[ nIndex ]->aData );
343 uno::Reference< sdbc::XRow > xRow
344 = HierarchyContent::getPropertyValues(
345 m_pImpl->m_xContext,
346 getResultSet()->getProperties(),
347 aData,
348 static_cast< HierarchyContentProvider * >(
349 m_pImpl->m_xContent->getProvider().get() ),
350 queryContentIdentifierString( nIndex ) );
351 m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
352 return xRow;
355 return uno::Reference< sdbc::XRow >();
359 // virtual
360 void HierarchyResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
362 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
364 if ( nIndex < m_pImpl->m_aResults.size() )
365 m_pImpl->m_aResults[ nIndex ]->xRow.clear();
369 // virtual
370 void HierarchyResultSetDataSupplier::close()
375 // virtual
376 void HierarchyResultSetDataSupplier::validate()
381 bool HierarchyResultSetDataSupplier::checkResult(
382 const HierarchyEntryData& rResult )
384 switch ( m_pImpl->m_nOpenMode )
386 case ucb::OpenMode::FOLDERS:
387 if ( rResult.getType() == HierarchyEntryData::LINK )
389 // Entry is a link.
390 return false;
392 break;
394 case ucb::OpenMode::DOCUMENTS:
395 if ( rResult.getType() == HierarchyEntryData::FOLDER )
397 // Entry is a folder.
398 return false;
400 break;
402 case ucb::OpenMode::ALL:
403 default:
404 break;
407 return true;
410 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */