Bump for 3.6-28
[LibreOffice.git] / ucb / source / ucp / webdav / webdavdatasupplier.cxx
blobf5f6620629737f6c920f34c07cca8599b9feba63
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 *************************************************************************/
35 #include <osl/diagnose.h>
36 #include <com/sun/star/ucb/OpenMode.hpp>
37 #include <ucbhelper/contentidentifier.hxx>
38 #include <ucbhelper/providerhelper.hxx>
39 #include "webdavdatasupplier.hxx"
40 #include "webdavcontent.hxx"
41 #include "ContentProperties.hxx"
42 #include "DAVSession.hxx"
43 #include "NeonUri.hxx"
45 using namespace com::sun::star;
46 using namespace webdav_ucp;
48 namespace webdav_ucp
51 //=========================================================================
53 // struct ResultListEntry.
55 //=========================================================================
57 struct ResultListEntry
59 rtl::OUString aId;
60 uno::Reference< ucb::XContentIdentifier > xId;
61 uno::Reference< ucb::XContent > xContent;
62 uno::Reference< sdbc::XRow > xRow;
63 const ContentProperties* pData;
65 ResultListEntry( const ContentProperties* pEntry ) : pData( pEntry ) {};
66 ~ResultListEntry() { delete pData; }
69 //=========================================================================
71 // ResultList.
73 //=========================================================================
75 typedef std::vector< ResultListEntry* > ResultList;
77 //=========================================================================
79 // struct DataSupplier_Impl.
81 //=========================================================================
83 struct DataSupplier_Impl
85 osl::Mutex m_aMutex;
86 ResultList m_aResults;
87 rtl::Reference< Content > m_xContent;
88 uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
89 sal_Int32 m_nOpenMode;
90 sal_Bool m_bCountFinal;
91 sal_Bool m_bThrowException;
93 DataSupplier_Impl(
94 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
95 const rtl::Reference< Content >& rContent,
96 sal_Int32 nOpenMode )
97 : m_xContent( rContent ), m_xSMgr( rxSMgr ), m_nOpenMode( nOpenMode ),
98 m_bCountFinal( sal_False ), m_bThrowException( sal_False ) {}
99 ~DataSupplier_Impl();
102 //=========================================================================
103 DataSupplier_Impl::~DataSupplier_Impl()
105 ResultList::const_iterator it = m_aResults.begin();
106 ResultList::const_iterator end = m_aResults.end();
108 while ( it != end )
110 delete (*it);
111 ++it;
117 //=========================================================================
118 //=========================================================================
120 // DataSupplier Implementation.
122 //=========================================================================
123 //=========================================================================
125 DataSupplier::DataSupplier(
126 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
127 const rtl::Reference< Content >& rContent,
128 sal_Int32 nOpenMode )
129 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
133 //=========================================================================
134 // virtual
135 DataSupplier::~DataSupplier()
137 delete m_pImpl;
140 //=========================================================================
141 // virtual
142 rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
144 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
146 if ( nIndex < m_pImpl->m_aResults.size() )
148 rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
149 if ( !aId.isEmpty() )
151 // Already cached.
152 return aId;
156 if ( getResult( nIndex ) )
158 rtl::OUString aId = m_pImpl->m_xContent->getResourceAccess().getURL();
160 const ContentProperties& props
161 = *( m_pImpl->m_aResults[ nIndex ]->pData );
163 if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
164 aId += rtl::OUString("/");
166 aId += props.getEscapedTitle();
168 if ( props.isTrailingSlash() )
169 aId += rtl::OUString("/");
171 m_pImpl->m_aResults[ nIndex ]->aId = aId;
172 return aId;
174 return rtl::OUString();
177 //=========================================================================
178 // virtual
179 uno::Reference< ucb::XContentIdentifier >
180 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
182 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
184 if ( nIndex < m_pImpl->m_aResults.size() )
186 uno::Reference< ucb::XContentIdentifier > xId
187 = m_pImpl->m_aResults[ nIndex ]->xId;
188 if ( xId.is() )
190 // Already cached.
191 return xId;
195 rtl::OUString aId = queryContentIdentifierString( nIndex );
196 if ( !aId.isEmpty() )
198 uno::Reference< ucb::XContentIdentifier > xId
199 = new ::ucbhelper::ContentIdentifier( aId );
200 m_pImpl->m_aResults[ nIndex ]->xId = xId;
201 return xId;
203 return uno::Reference< ucb::XContentIdentifier >();
206 //=========================================================================
207 // virtual
208 uno::Reference< ucb::XContent >
209 DataSupplier::queryContent( sal_uInt32 nIndex )
211 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
213 if ( nIndex < m_pImpl->m_aResults.size() )
215 uno::Reference< ucb::XContent > xContent
216 = m_pImpl->m_aResults[ nIndex ]->xContent;
217 if ( xContent.is() )
219 // Already cached.
220 return xContent;
224 uno::Reference< ucb::XContentIdentifier > xId
225 = queryContentIdentifier( nIndex );
226 if ( xId.is() )
230 uno::Reference< ucb::XContent > xContent
231 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
232 m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
233 return xContent;
236 catch ( ucb::IllegalIdentifierException& )
240 return uno::Reference< ucb::XContent >();
243 //=========================================================================
244 // virtual
245 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
247 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
249 if ( m_pImpl->m_aResults.size() > nIndex )
251 // Result already present.
252 return sal_True;
255 // Obtain values...
256 if ( getData() )
258 if ( m_pImpl->m_aResults.size() > nIndex )
260 // Result already present.
261 return sal_True;
265 return sal_False;
268 //=========================================================================
269 // virtual
270 sal_uInt32 DataSupplier::totalCount()
272 // Obtain values...
273 getData();
275 return m_pImpl->m_aResults.size();
278 //=========================================================================
279 // virtual
280 sal_uInt32 DataSupplier::currentCount()
282 return m_pImpl->m_aResults.size();
285 //=========================================================================
286 // virtual
287 sal_Bool DataSupplier::isCountFinal()
289 return m_pImpl->m_bCountFinal;
292 //=========================================================================
293 // virtual
294 uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues(
295 sal_uInt32 nIndex )
297 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
299 if ( nIndex < m_pImpl->m_aResults.size() )
301 uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
302 if ( xRow.is() )
304 // Already cached.
305 return xRow;
309 if ( getResult( nIndex ) )
311 uno::Reference< sdbc::XRow > xRow
312 = Content::getPropertyValues(
313 m_pImpl->m_xSMgr,
314 getResultSet()->getProperties(),
315 *(m_pImpl->m_aResults[ nIndex ]->pData),
316 rtl::Reference< ::ucbhelper::ContentProviderImplHelper >(
317 m_pImpl->m_xContent->getProvider().get() ),
318 queryContentIdentifierString( nIndex ) );
319 m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
320 return xRow;
323 return uno::Reference< sdbc::XRow >();
326 //=========================================================================
327 // virtual
328 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
330 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
332 if ( nIndex < m_pImpl->m_aResults.size() )
333 m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
336 //=========================================================================
337 // virtual
338 void DataSupplier::close()
342 //=========================================================================
343 // virtual
344 void DataSupplier::validate()
345 throw( ucb::ResultSetException )
347 if ( m_pImpl->m_bThrowException )
348 throw ucb::ResultSetException();
351 //=========================================================================
352 sal_Bool DataSupplier::getData()
354 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
356 if ( !m_pImpl->m_bCountFinal )
358 std::vector< rtl::OUString > propertyNames;
359 ContentProperties::UCBNamesToDAVNames(
360 getResultSet()->getProperties(), propertyNames );
362 // Append "resourcetype", if not already present. It's value is
363 // needed to get a valid ContentProperties::pIsFolder value, which
364 // is needed for OpenMode handling.
366 std::vector< rtl::OUString >::const_iterator it
367 = propertyNames.begin();
368 std::vector< rtl::OUString >::const_iterator end
369 = propertyNames.end();
371 while ( it != end )
373 if ( (*it).equals( DAVProperties::RESOURCETYPE ) )
374 break;
376 ++it;
379 if ( it == end )
380 propertyNames.push_back( DAVProperties::RESOURCETYPE );
382 std::vector< DAVResource > resources;
385 // propfind depth 1, get property values for parent AND for each
386 // child
387 m_pImpl->m_xContent->getResourceAccess()
388 .PROPFIND( DAVONE,
389 propertyNames,
390 resources,
391 getResultSet()->getEnvironment() );
393 catch ( DAVException & )
395 // OSL_FAIL( "PROPFIND : DAVException" );
396 m_pImpl->m_bThrowException = sal_True;
399 if ( !m_pImpl->m_bThrowException )
403 NeonUri aURI(
404 m_pImpl->m_xContent->getResourceAccess().getURL() );
405 rtl::OUString aPath = aURI.GetPath();
407 if ( aPath.getStr()[ aPath.getLength() - 1 ]
408 == sal_Unicode( '/' ) )
409 aPath = aPath.copy( 0, aPath.getLength() - 1 );
411 aPath = NeonUri::unescape( aPath );
412 bool bFoundParent = false;
414 for ( sal_uInt32 n = 0; n < resources.size(); ++n )
416 const DAVResource & rRes = resources[ n ];
418 // Filter parent, which is contained somewhere(!) in
419 // the vector.
420 if ( !bFoundParent )
424 NeonUri aCurrURI( rRes.uri );
425 rtl::OUString aCurrPath = aCurrURI.GetPath();
426 if ( aCurrPath.getStr()[
427 aCurrPath.getLength() - 1 ]
428 == sal_Unicode( '/' ) )
429 aCurrPath
430 = aCurrPath.copy(
432 aCurrPath.getLength() - 1 );
434 aCurrPath = NeonUri::unescape( aCurrPath );
435 if ( aPath == aCurrPath )
437 bFoundParent = true;
438 continue;
441 catch ( DAVException const & )
443 // do nothing, ignore error. continue.
447 ContentProperties* pContentProperties
448 = new ContentProperties( rRes );
450 // Check resource against open mode.
451 switch ( m_pImpl->m_nOpenMode )
453 case ucb::OpenMode::FOLDERS:
455 sal_Bool bFolder = sal_False;
457 const uno::Any & rValue
458 = pContentProperties->getValue(
459 rtl::OUString( "IsFolder" ) );
460 rValue >>= bFolder;
462 if ( !bFolder )
463 continue;
465 break;
468 case ucb::OpenMode::DOCUMENTS:
470 sal_Bool bDocument = sal_False;
472 const uno::Any & rValue
473 = pContentProperties->getValue(
474 rtl::OUString( "IsDocument" ) );
475 rValue >>= bDocument;
477 if ( !bDocument )
478 continue;
480 break;
483 case ucb::OpenMode::ALL:
484 default:
485 break;
488 m_pImpl->m_aResults.push_back(
489 new ResultListEntry( pContentProperties ) );
492 catch ( DAVException const & )
497 m_pImpl->m_bCountFinal = sal_True;
499 // Callback possible, because listeners may be informed!
500 aGuard.clear();
501 getResultSet()->rowCountFinal();
503 return !m_pImpl->m_bThrowException;
506 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */