bump product version to 7.2.5.1
[LibreOffice.git] / ucb / source / ucp / webdav-neon / webdavdatasupplier.cxx
blob6acadda6a6fd6de2e63657709615c3473ea9bbca
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 /**************************************************************************
31 TODO
32 **************************************************************************
34 *************************************************************************/
36 #include <sal/log.hxx>
37 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
38 #include <com/sun/star/ucb/OpenMode.hpp>
39 #include <com/sun/star/ucb/ResultSetException.hpp>
40 #include <ucbhelper/contentidentifier.hxx>
41 #include <ucbhelper/providerhelper.hxx>
42 #include <tools/diagnose_ex.h>
43 #include <memory>
44 #include <vector>
45 #include "webdavdatasupplier.hxx"
46 #include "webdavcontent.hxx"
47 #include "ContentProperties.hxx"
48 #include "NeonUri.hxx"
50 using namespace com::sun::star;
51 using namespace webdav_ucp;
53 namespace webdav_ucp
57 // struct ResultListEntry.
59 namespace {
61 struct ResultListEntry
63 OUString aId;
64 uno::Reference< ucb::XContentIdentifier > xId;
65 uno::Reference< ucb::XContent > xContent;
66 uno::Reference< sdbc::XRow > xRow;
67 std::shared_ptr<ContentProperties> const pData;
69 explicit ResultListEntry(std::shared_ptr<ContentProperties> const& pEntry)
70 : pData(pEntry)
76 // ResultList.
79 typedef std::vector<std::unique_ptr<ResultListEntry>> ResultList;
82 // struct DataSupplier_Impl.
85 struct DataSupplier_Impl
87 osl::Mutex m_aMutex;
88 ResultList m_Results;
89 rtl::Reference< Content > m_xContent;
90 uno::Reference< uno::XComponentContext > m_xContext;
91 sal_Int32 m_nOpenMode;
92 bool m_bCountFinal;
93 bool m_bThrowException;
95 DataSupplier_Impl(
96 const uno::Reference< uno::XComponentContext >& rxContext,
97 const rtl::Reference< Content >& rContent,
98 sal_Int32 nOpenMode )
99 : m_xContent( rContent ), m_xContext( rxContext ), m_nOpenMode( nOpenMode ),
100 m_bCountFinal( false ), m_bThrowException( false ) {}
106 // DataSupplier Implementation.
109 DataSupplier::DataSupplier(
110 const uno::Reference< uno::XComponentContext >& rxContext,
111 const rtl::Reference< Content >& rContent,
112 sal_Int32 nOpenMode )
113 : m_pImpl( new DataSupplier_Impl( rxContext, rContent, nOpenMode ) )
118 // virtual
119 DataSupplier::~DataSupplier()
124 // virtual
125 OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
127 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
129 if (nIndex < m_pImpl->m_Results.size())
131 OUString aId = m_pImpl->m_Results[ nIndex ]->aId;
132 if ( !aId.isEmpty() )
134 // Already cached.
135 return aId;
139 if ( getResult( nIndex ) )
141 OUString aId = m_pImpl->m_xContent->getResourceAccess().getURL();
143 const ContentProperties& props(*(m_pImpl->m_Results[ nIndex ]->pData));
145 if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
146 aId += "/";
148 aId += props.getEscapedTitle();
150 if ( props.isTrailingSlash() )
151 aId += "/";
153 m_pImpl->m_Results[ nIndex ]->aId = aId;
154 return aId;
156 return OUString();
160 // virtual
161 uno::Reference< ucb::XContentIdentifier >
162 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
164 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
166 if (nIndex < m_pImpl->m_Results.size())
168 uno::Reference< ucb::XContentIdentifier > xId
169 = m_pImpl->m_Results[ nIndex ]->xId;
170 if ( xId.is() )
172 // Already cached.
173 return xId;
177 OUString aId = queryContentIdentifierString( nIndex );
178 if ( !aId.isEmpty() )
180 uno::Reference< ucb::XContentIdentifier > xId
181 = new ::ucbhelper::ContentIdentifier( aId );
182 m_pImpl->m_Results[ nIndex ]->xId = xId;
183 return xId;
185 return uno::Reference< ucb::XContentIdentifier >();
189 // virtual
190 uno::Reference< ucb::XContent >
191 DataSupplier::queryContent( sal_uInt32 nIndex )
193 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
195 if (nIndex < m_pImpl->m_Results.size())
197 uno::Reference< ucb::XContent > xContent
198 = m_pImpl->m_Results[ nIndex ]->xContent;
199 if ( xContent.is() )
201 // Already cached.
202 return xContent;
206 uno::Reference< ucb::XContentIdentifier > xId
207 = queryContentIdentifier( nIndex );
208 if ( xId.is() )
212 uno::Reference< ucb::XContent > xContent
213 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
214 m_pImpl->m_Results[ nIndex ]->xContent = xContent;
215 return xContent;
218 catch ( ucb::IllegalIdentifierException& )
222 return uno::Reference< ucb::XContent >();
226 // virtual
227 bool DataSupplier::getResult( sal_uInt32 nIndex )
229 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
231 if (nIndex < m_pImpl->m_Results.size())
233 // Result already present.
234 return true;
237 // Obtain values...
238 if ( getData() )
240 if (nIndex < m_pImpl->m_Results.size())
242 // Result already present.
243 return true;
247 return false;
251 // virtual
252 sal_uInt32 DataSupplier::totalCount()
254 // Obtain values...
255 getData();
257 return m_pImpl->m_Results.size();
261 // virtual
262 sal_uInt32 DataSupplier::currentCount()
264 return m_pImpl->m_Results.size();
268 // virtual
269 bool DataSupplier::isCountFinal()
271 return m_pImpl->m_bCountFinal;
275 // virtual
276 uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues(
277 sal_uInt32 nIndex )
279 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
281 if (nIndex < m_pImpl->m_Results.size())
283 uno::Reference< sdbc::XRow > xRow = m_pImpl->m_Results[ nIndex ]->xRow;
284 if ( xRow.is() )
286 // Already cached.
287 return xRow;
291 if ( getResult( nIndex ) )
293 uno::Reference< sdbc::XRow > xRow
294 = Content::getPropertyValues(
295 m_pImpl->m_xContext,
296 getResultSet()->getProperties(),
297 *(m_pImpl->m_Results[ nIndex ]->pData),
298 m_pImpl->m_xContent->getProvider(),
299 queryContentIdentifierString( nIndex ) );
300 m_pImpl->m_Results[ nIndex ]->xRow = xRow;
301 return xRow;
304 return uno::Reference< sdbc::XRow >();
308 // virtual
309 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
311 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
313 if (nIndex < m_pImpl->m_Results.size())
314 m_pImpl->m_Results[ nIndex ]->xRow.clear();
318 // virtual
319 void DataSupplier::close()
324 // virtual
325 void DataSupplier::validate()
327 if ( m_pImpl->m_bThrowException )
328 throw ucb::ResultSetException();
332 bool DataSupplier::getData()
334 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
336 if ( !m_pImpl->m_bCountFinal )
338 std::vector< OUString > propertyNames;
339 ContentProperties::UCBNamesToDAVNames(
340 getResultSet()->getProperties(), propertyNames );
342 // Append "resourcetype", if not already present. It's value is
343 // needed to get a valid ContentProperties::pIsFolder value, which
344 // is needed for OpenMode handling.
346 bool isNoResourceType = std::none_of(propertyNames.begin(), propertyNames.end(),
347 [](const OUString& rName) { return rName == DAVProperties::RESOURCETYPE; });
349 if ( isNoResourceType )
350 propertyNames.push_back( DAVProperties::RESOURCETYPE );
352 std::vector< DAVResource > resources;
355 // propfind depth 1, get property values for parent AND for each
356 // child
357 m_pImpl->m_xContent->getResourceAccess()
358 .PROPFIND( DAVONE,
359 propertyNames,
360 resources,
361 getResultSet()->getEnvironment() );
362 #if defined SAL_LOG_INFO
364 //print the resource for every URI returned
365 for ( const auto& rResource : resources )
367 NeonUri aCurrURI( rResource.uri );
368 OUString aCurrPath = aCurrURI.GetPath();
369 aCurrPath = NeonUri::unescape( aCurrPath );
370 SAL_INFO( "ucb.ucp.webdav", "getData() - resource URL: <" << rResource.uri << ">, unescaped to: <" << aCurrPath << "> )" );
371 for ( const auto& rProp : rResource.properties )
373 SAL_INFO( "ucb.ucp.webdav", "PROPFIND - property name: " << rProp.Name );
377 #endif
379 catch ( DAVException & )
381 TOOLS_WARN_EXCEPTION( "ucb.ucp.webdav", "Running PROPFIND: DAVException" );
382 m_pImpl->m_bThrowException = true;
385 if ( !m_pImpl->m_bThrowException )
389 NeonUri aURI(
390 m_pImpl->m_xContent->getResourceAccess().getURL() );
391 OUString aPath = aURI.GetPath();
393 if ( aPath.endsWith("/") )
394 aPath = aPath.copy( 0, aPath.getLength() - 1 );
396 aPath = NeonUri::unescape( aPath );
397 bool bFoundParent = false;
399 for (DAVResource & rRes : resources)
401 // Filter parent, which is contained somewhere(!) in
402 // the vector.
403 if ( !bFoundParent )
407 NeonUri aCurrURI( rRes.uri );
408 OUString aCurrPath = aCurrURI.GetPath();
409 if ( aCurrPath.endsWith("/") )
410 aCurrPath
411 = aCurrPath.copy(
413 aCurrPath.getLength() - 1 );
415 aCurrPath = NeonUri::unescape( aCurrPath );
416 if ( aPath == aCurrPath )
418 bFoundParent = true;
419 continue;
422 catch ( DAVException const & )
424 // do nothing, ignore error. continue.
428 std::shared_ptr<ContentProperties> const
429 pContentProperties = std::make_shared<ContentProperties>(rRes);
431 // Check resource against open mode.
432 switch ( m_pImpl->m_nOpenMode )
434 case ucb::OpenMode::FOLDERS:
436 bool bFolder = false;
438 const uno::Any & rValue
439 = pContentProperties->getValue(
440 "IsFolder" );
441 rValue >>= bFolder;
443 if ( !bFolder )
444 continue;
446 break;
449 case ucb::OpenMode::DOCUMENTS:
451 bool bDocument = false;
453 const uno::Any & rValue
454 = pContentProperties->getValue(
455 "IsDocument" );
456 rValue >>= bDocument;
458 if ( !bDocument )
459 continue;
461 break;
464 case ucb::OpenMode::ALL:
465 default:
466 break;
469 m_pImpl->m_Results.push_back(
470 std::make_unique<ResultListEntry>(pContentProperties));
473 catch ( DAVException const & )
478 m_pImpl->m_bCountFinal = true;
480 // Callback possible, because listeners may be informed!
481 aGuard.clear();
482 getResultSet()->rowCountFinal();
484 return !m_pImpl->m_bThrowException;
487 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */