Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / ucb / source / ucp / webdav / webdavdatasupplier.cxx
blob2d01a1eac1f80c893c14a6ea80d500b53a41ef89
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 .
20 #include <osl/diagnose.h>
21 #include <com/sun/star/ucb/OpenMode.hpp>
22 #include <ucbhelper/contentidentifier.hxx>
23 #include <ucbhelper/providerhelper.hxx>
24 #include "webdavdatasupplier.hxx"
25 #include "webdavcontent.hxx"
26 #include "ContentProperties.hxx"
27 #ifndef _WEBDAV_SESSION_HXX
28 #include "DAVSession.hxx"
29 #endif
30 #include "SerfUri.hxx"
32 using namespace com::sun::star;
33 using namespace http_dav_ucp;
35 namespace http_dav_ucp
38 //=========================================================================
40 // struct ResultListEntry.
42 //=========================================================================
44 struct ResultListEntry
46 rtl::OUString aId;
47 uno::Reference< ucb::XContentIdentifier > xId;
48 uno::Reference< ucb::XContent > xContent;
49 uno::Reference< sdbc::XRow > xRow;
50 const ContentProperties* pData;
52 ResultListEntry( const ContentProperties* pEntry ) : pData( pEntry ) {};
53 ~ResultListEntry() { delete pData; }
56 //=========================================================================
58 // ResultList.
60 //=========================================================================
62 typedef std::vector< ResultListEntry* > ResultList;
64 //=========================================================================
66 // struct DataSupplier_Impl.
68 //=========================================================================
70 struct DataSupplier_Impl
72 osl::Mutex m_aMutex;
73 ResultList m_aResults;
74 rtl::Reference< Content > m_xContent;
75 uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
76 sal_Int32 m_nOpenMode;
77 sal_Bool m_bCountFinal;
78 sal_Bool m_bThrowException;
80 DataSupplier_Impl(
81 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
82 const rtl::Reference< Content >& rContent,
83 sal_Int32 nOpenMode )
84 : m_xContent( rContent ), m_xSMgr( rxSMgr ), m_nOpenMode( nOpenMode ),
85 m_bCountFinal( sal_False ), m_bThrowException( sal_False ) {}
86 ~DataSupplier_Impl();
89 //=========================================================================
90 DataSupplier_Impl::~DataSupplier_Impl()
92 ResultList::const_iterator it = m_aResults.begin();
93 ResultList::const_iterator end = m_aResults.end();
95 while ( it != end )
97 delete (*it);
98 ++it;
104 //=========================================================================
105 //=========================================================================
107 // DataSupplier Implementation.
109 //=========================================================================
110 //=========================================================================
112 DataSupplier::DataSupplier(
113 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
114 const rtl::Reference< Content >& rContent,
115 sal_Int32 nOpenMode )
116 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
120 //=========================================================================
121 // virtual
122 DataSupplier::~DataSupplier()
124 delete m_pImpl;
127 //=========================================================================
128 // virtual
129 rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
131 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
133 if ( nIndex < m_pImpl->m_aResults.size() )
135 rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
136 if ( aId.getLength() )
138 // Already cached.
139 return aId;
143 if ( getResult( nIndex ) )
145 rtl::OUString aId = m_pImpl->m_xContent->getResourceAccess().getURL();
147 const ContentProperties& props
148 = *( m_pImpl->m_aResults[ nIndex ]->pData );
150 if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
151 aId += rtl::OUString::createFromAscii( "/" );
153 aId += props.getEscapedTitle();
155 if ( props.isTrailingSlash() )
156 aId += rtl::OUString::createFromAscii( "/" );
158 m_pImpl->m_aResults[ nIndex ]->aId = aId;
159 return aId;
161 return rtl::OUString();
164 //=========================================================================
165 // virtual
166 uno::Reference< ucb::XContentIdentifier >
167 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
169 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
171 if ( nIndex < m_pImpl->m_aResults.size() )
173 uno::Reference< ucb::XContentIdentifier > xId
174 = m_pImpl->m_aResults[ nIndex ]->xId;
175 if ( xId.is() )
177 // Already cached.
178 return xId;
182 rtl::OUString aId = queryContentIdentifierString( nIndex );
183 if ( aId.getLength() )
185 uno::Reference< ucb::XContentIdentifier > xId
186 = new ::ucbhelper::ContentIdentifier( aId );
187 m_pImpl->m_aResults[ nIndex ]->xId = xId;
188 return xId;
190 return uno::Reference< ucb::XContentIdentifier >();
193 //=========================================================================
194 // virtual
195 uno::Reference< ucb::XContent >
196 DataSupplier::queryContent( sal_uInt32 nIndex )
198 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
200 if ( nIndex < m_pImpl->m_aResults.size() )
202 uno::Reference< ucb::XContent > xContent
203 = m_pImpl->m_aResults[ nIndex ]->xContent;
204 if ( xContent.is() )
206 // Already cached.
207 return xContent;
211 uno::Reference< ucb::XContentIdentifier > xId
212 = queryContentIdentifier( nIndex );
213 if ( xId.is() )
217 uno::Reference< ucb::XContent > xContent
218 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
219 m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
220 return xContent;
223 catch ( ucb::IllegalIdentifierException& )
227 return uno::Reference< ucb::XContent >();
230 //=========================================================================
231 // virtual
232 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
234 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
236 if ( m_pImpl->m_aResults.size() > nIndex )
238 // Result already present.
239 return sal_True;
242 // Obtain values...
243 if ( getData() )
245 if ( m_pImpl->m_aResults.size() > nIndex )
247 // Result already present.
248 return sal_True;
252 return sal_False;
255 //=========================================================================
256 // virtual
257 sal_uInt32 DataSupplier::totalCount()
259 // Obtain values...
260 getData();
262 return m_pImpl->m_aResults.size();
265 //=========================================================================
266 // virtual
267 sal_uInt32 DataSupplier::currentCount()
269 return m_pImpl->m_aResults.size();
272 //=========================================================================
273 // virtual
274 sal_Bool DataSupplier::isCountFinal()
276 return m_pImpl->m_bCountFinal;
279 //=========================================================================
280 // virtual
281 uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues(
282 sal_uInt32 nIndex )
284 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
286 if ( nIndex < m_pImpl->m_aResults.size() )
288 uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
289 if ( xRow.is() )
291 // Already cached.
292 return xRow;
296 if ( getResult( nIndex ) )
298 uno::Reference< sdbc::XRow > xRow
299 = Content::getPropertyValues(
300 m_pImpl->m_xSMgr,
301 getResultSet()->getProperties(),
302 *(m_pImpl->m_aResults[ nIndex ]->pData),
303 rtl::Reference< ::ucbhelper::ContentProviderImplHelper >(
304 m_pImpl->m_xContent->getProvider().get() ),
305 queryContentIdentifierString( nIndex ) );
306 m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
307 return xRow;
310 return uno::Reference< sdbc::XRow >();
313 //=========================================================================
314 // virtual
315 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
317 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
319 if ( nIndex < m_pImpl->m_aResults.size() )
320 m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
323 //=========================================================================
324 // virtual
325 void DataSupplier::close()
329 //=========================================================================
330 // virtual
331 void DataSupplier::validate()
332 throw( ucb::ResultSetException )
334 if ( m_pImpl->m_bThrowException )
335 throw ucb::ResultSetException();
338 //=========================================================================
339 sal_Bool DataSupplier::getData()
341 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
343 if ( !m_pImpl->m_bCountFinal )
345 std::vector< rtl::OUString > propertyNames;
346 ContentProperties::UCBNamesToDAVNames(
347 getResultSet()->getProperties(), propertyNames );
349 // Append "resourcetype", if not already present. It's value is
350 // needed to get a valid ContentProperties::pIsFolder value, which
351 // is needed for OpenMode handling.
353 std::vector< rtl::OUString >::const_iterator it
354 = propertyNames.begin();
355 std::vector< rtl::OUString >::const_iterator end
356 = propertyNames.end();
358 while ( it != end )
360 if ( (*it).equals( DAVProperties::RESOURCETYPE ) )
361 break;
363 ++it;
366 if ( it == end )
367 propertyNames.push_back( DAVProperties::RESOURCETYPE );
369 std::vector< DAVResource > resources;
372 // propfind depth 1, get property values for parent AND for each
373 // child
374 m_pImpl->m_xContent->getResourceAccess()
375 .PROPFIND( DAVONE,
376 propertyNames,
377 resources,
378 getResultSet()->getEnvironment() );
380 catch ( DAVException & )
382 // OSL_ENSURE( sal_False, "PROPFIND : DAVException" );
383 m_pImpl->m_bThrowException = sal_True;
386 if ( !m_pImpl->m_bThrowException )
390 SerfUri aURI(
391 m_pImpl->m_xContent->getResourceAccess().getURL() );
392 rtl::OUString aPath = aURI.GetPath();
394 if ( aPath.getStr()[ aPath.getLength() - 1 ]
395 == sal_Unicode( '/' ) )
396 aPath = aPath.copy( 0, aPath.getLength() - 1 );
398 aPath = SerfUri::unescape( aPath );
399 bool bFoundParent = false;
401 for ( sal_uInt32 n = 0; n < resources.size(); ++n )
403 const DAVResource & rRes = resources[ n ];
405 // Filter parent, which is contained somewhere(!) in
406 // the vector.
407 if ( !bFoundParent )
411 SerfUri aCurrURI( rRes.uri );
412 rtl::OUString aCurrPath = aCurrURI.GetPath();
413 if ( aCurrPath.getStr()[
414 aCurrPath.getLength() - 1 ]
415 == sal_Unicode( '/' ) )
416 aCurrPath
417 = aCurrPath.copy(
419 aCurrPath.getLength() - 1 );
421 aCurrPath = SerfUri::unescape( aCurrPath );
422 if ( aPath == aCurrPath )
424 bFoundParent = true;
425 continue;
428 catch ( DAVException const & )
430 // do nothing, ignore error. continue.
434 ContentProperties* pContentProperties
435 = new ContentProperties( rRes );
437 // Check resource against open mode.
438 switch ( m_pImpl->m_nOpenMode )
440 case ucb::OpenMode::FOLDERS:
442 sal_Bool bFolder = sal_False;
444 const uno::Any & rValue
445 = pContentProperties->getValue(
446 rtl::OUString(
447 RTL_CONSTASCII_USTRINGPARAM(
448 "IsFolder" ) ) );
449 rValue >>= bFolder;
451 if ( !bFolder )
452 continue;
454 break;
457 case ucb::OpenMode::DOCUMENTS:
459 sal_Bool bDocument = sal_False;
461 const uno::Any & rValue
462 = pContentProperties->getValue(
463 rtl::OUString(
464 RTL_CONSTASCII_USTRINGPARAM(
465 "IsDocument" ) ) );
466 rValue >>= bDocument;
468 if ( !bDocument )
469 continue;
471 break;
474 case ucb::OpenMode::ALL:
475 default:
476 break;
479 m_pImpl->m_aResults.push_back(
480 new ResultListEntry( pContentProperties ) );
483 catch ( DAVException const & )
488 m_pImpl->m_bCountFinal = sal_True;
490 // Callback possible, because listeners may be informed!
491 aGuard.clear();
492 getResultSet()->rowCountFinal();
494 return !m_pImpl->m_bThrowException;
497 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */