bump product version to 5.0.4.1
[LibreOffice.git] / ucb / source / ucp / webdav-neon / webdavdatasupplier.cxx
bloba01b1a0436d2a0cb8e4436b4ea599385d88370a2
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 <boost/ptr_container/ptr_vector.hpp>
36 #include <boost/shared_ptr.hpp>
37 #include <osl/diagnose.h>
38 #include <com/sun/star/ucb/OpenMode.hpp>
39 #include <ucbhelper/contentidentifier.hxx>
40 #include <ucbhelper/providerhelper.hxx>
41 #include "webdavdatasupplier.hxx"
42 #include "webdavcontent.hxx"
43 #include "ContentProperties.hxx"
44 #include "DAVSession.hxx"
45 #include "NeonUri.hxx"
47 using namespace com::sun::star;
48 using namespace webdav_ucp;
50 namespace webdav_ucp
55 // struct ResultListEntry.
59 struct ResultListEntry
61 OUString aId;
62 uno::Reference< ucb::XContentIdentifier > xId;
63 uno::Reference< ucb::XContent > xContent;
64 uno::Reference< sdbc::XRow > xRow;
65 boost::shared_ptr<ContentProperties> const pData;
67 ResultListEntry(boost::shared_ptr<ContentProperties> const& pEntry)
68 : pData(pEntry)
74 // ResultList.
78 typedef boost::ptr_vector<ResultListEntry> ResultList;
82 // struct DataSupplier_Impl.
86 struct DataSupplier_Impl
88 osl::Mutex m_aMutex;
89 ResultList m_aResults;
90 rtl::Reference< Content > m_xContent;
91 uno::Reference< uno::XComponentContext > m_xContext;
92 sal_Int32 m_nOpenMode;
93 bool m_bCountFinal;
94 bool m_bThrowException;
96 DataSupplier_Impl(
97 const uno::Reference< uno::XComponentContext >& rxContext,
98 const rtl::Reference< Content >& rContent,
99 sal_Int32 nOpenMode )
100 : m_xContent( rContent ), m_xContext( rxContext ), m_nOpenMode( nOpenMode ),
101 m_bCountFinal( false ), m_bThrowException( false ) {}
109 // DataSupplier Implementation.
114 DataSupplier::DataSupplier(
115 const uno::Reference< uno::XComponentContext >& rxContext,
116 const rtl::Reference< Content >& rContent,
117 sal_Int32 nOpenMode )
118 : m_pImpl( new DataSupplier_Impl( rxContext, rContent, nOpenMode ) )
123 // virtual
124 DataSupplier::~DataSupplier()
129 // virtual
130 OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
132 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
134 if ( nIndex < m_pImpl->m_aResults.size() )
136 OUString aId = m_pImpl->m_aResults[ nIndex ].aId;
137 if ( !aId.isEmpty() )
139 // Already cached.
140 return aId;
144 if ( getResult( nIndex ) )
146 OUString aId = m_pImpl->m_xContent->getResourceAccess().getURL();
148 const ContentProperties& props
149 = *( m_pImpl->m_aResults[ nIndex ].pData );
151 if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
152 aId += "/";
154 aId += props.getEscapedTitle();
156 if ( props.isTrailingSlash() )
157 aId += "/";
159 m_pImpl->m_aResults[ nIndex ].aId = aId;
160 return aId;
162 return OUString();
166 // virtual
167 uno::Reference< ucb::XContentIdentifier >
168 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
170 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
172 if ( nIndex < m_pImpl->m_aResults.size() )
174 uno::Reference< ucb::XContentIdentifier > xId
175 = m_pImpl->m_aResults[ nIndex ].xId;
176 if ( xId.is() )
178 // Already cached.
179 return xId;
183 OUString aId = queryContentIdentifierString( nIndex );
184 if ( !aId.isEmpty() )
186 uno::Reference< ucb::XContentIdentifier > xId
187 = new ::ucbhelper::ContentIdentifier( aId );
188 m_pImpl->m_aResults[ nIndex ].xId = xId;
189 return xId;
191 return uno::Reference< ucb::XContentIdentifier >();
195 // virtual
196 uno::Reference< ucb::XContent >
197 DataSupplier::queryContent( sal_uInt32 nIndex )
199 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
201 if ( nIndex < m_pImpl->m_aResults.size() )
203 uno::Reference< ucb::XContent > xContent
204 = m_pImpl->m_aResults[ nIndex ].xContent;
205 if ( xContent.is() )
207 // Already cached.
208 return xContent;
212 uno::Reference< ucb::XContentIdentifier > xId
213 = queryContentIdentifier( nIndex );
214 if ( xId.is() )
218 uno::Reference< ucb::XContent > xContent
219 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
220 m_pImpl->m_aResults[ nIndex ].xContent = xContent;
221 return xContent;
224 catch ( ucb::IllegalIdentifierException& )
228 return uno::Reference< ucb::XContent >();
232 // virtual
233 bool DataSupplier::getResult( sal_uInt32 nIndex )
235 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
237 if ( m_pImpl->m_aResults.size() > nIndex )
239 // Result already present.
240 return true;
243 // Obtain values...
244 if ( getData() )
246 if ( m_pImpl->m_aResults.size() > nIndex )
248 // Result already present.
249 return true;
253 return false;
257 // virtual
258 sal_uInt32 DataSupplier::totalCount()
260 // Obtain values...
261 getData();
263 return m_pImpl->m_aResults.size();
267 // virtual
268 sal_uInt32 DataSupplier::currentCount()
270 return m_pImpl->m_aResults.size();
274 // virtual
275 bool DataSupplier::isCountFinal()
277 return m_pImpl->m_bCountFinal;
281 // virtual
282 uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues(
283 sal_uInt32 nIndex )
285 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
287 if ( nIndex < m_pImpl->m_aResults.size() )
289 uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ].xRow;
290 if ( xRow.is() )
292 // Already cached.
293 return xRow;
297 if ( getResult( nIndex ) )
299 uno::Reference< sdbc::XRow > xRow
300 = Content::getPropertyValues(
301 m_pImpl->m_xContext,
302 getResultSet()->getProperties(),
303 *(m_pImpl->m_aResults[ nIndex ].pData),
304 rtl::Reference< ::ucbhelper::ContentProviderImplHelper >(
305 m_pImpl->m_xContent->getProvider().get() ),
306 queryContentIdentifierString( nIndex ) );
307 m_pImpl->m_aResults[ nIndex ].xRow = xRow;
308 return xRow;
311 return uno::Reference< sdbc::XRow >();
315 // virtual
316 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
318 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
320 if ( nIndex < m_pImpl->m_aResults.size() )
321 m_pImpl->m_aResults[ nIndex ].xRow = uno::Reference< sdbc::XRow >();
325 // virtual
326 void DataSupplier::close()
331 // virtual
332 void DataSupplier::validate()
333 throw( ucb::ResultSetException )
335 if ( m_pImpl->m_bThrowException )
336 throw ucb::ResultSetException();
340 bool DataSupplier::getData()
342 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
344 if ( !m_pImpl->m_bCountFinal )
346 std::vector< OUString > propertyNames;
347 ContentProperties::UCBNamesToDAVNames(
348 getResultSet()->getProperties(), propertyNames );
350 // Append "resourcetype", if not already present. It's value is
351 // needed to get a valid ContentProperties::pIsFolder value, which
352 // is needed for OpenMode handling.
354 std::vector< OUString >::const_iterator it
355 = propertyNames.begin();
356 std::vector< OUString >::const_iterator end
357 = propertyNames.end();
359 while ( it != end )
361 if ( (*it).equals( DAVProperties::RESOURCETYPE ) )
362 break;
364 ++it;
367 if ( it == end )
368 propertyNames.push_back( DAVProperties::RESOURCETYPE );
370 std::vector< DAVResource > resources;
373 // propfind depth 1, get property values for parent AND for each
374 // child
375 m_pImpl->m_xContent->getResourceAccess()
376 .PROPFIND( DAVONE,
377 propertyNames,
378 resources,
379 getResultSet()->getEnvironment() );
381 catch ( DAVException & )
383 // OSL_FAIL( "PROPFIND : DAVException" );
384 m_pImpl->m_bThrowException = true;
387 if ( !m_pImpl->m_bThrowException )
391 NeonUri aURI(
392 m_pImpl->m_xContent->getResourceAccess().getURL() );
393 OUString aPath = aURI.GetPath();
395 if ( aPath.endsWith("/") )
396 aPath = aPath.copy( 0, aPath.getLength() - 1 );
398 aPath = NeonUri::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 NeonUri aCurrURI( rRes.uri );
412 OUString aCurrPath = aCurrURI.GetPath();
413 if ( aCurrPath.endsWith("/") )
414 aCurrPath
415 = aCurrPath.copy(
417 aCurrPath.getLength() - 1 );
419 aCurrPath = NeonUri::unescape( aCurrPath );
420 if ( aPath == aCurrPath )
422 bFoundParent = true;
423 continue;
426 catch ( DAVException const & )
428 // do nothing, ignore error. continue.
432 boost::shared_ptr<ContentProperties> const
433 pContentProperties(new ContentProperties(rRes));
435 // Check resource against open mode.
436 switch ( m_pImpl->m_nOpenMode )
438 case ucb::OpenMode::FOLDERS:
440 bool bFolder = false;
442 const uno::Any & rValue
443 = pContentProperties->getValue(
444 OUString( "IsFolder" ) );
445 rValue >>= bFolder;
447 if ( !bFolder )
448 continue;
450 break;
453 case ucb::OpenMode::DOCUMENTS:
455 bool bDocument = false;
457 const uno::Any & rValue
458 = pContentProperties->getValue(
459 OUString( "IsDocument" ) );
460 rValue >>= bDocument;
462 if ( !bDocument )
463 continue;
465 break;
468 case ucb::OpenMode::ALL:
469 default:
470 break;
473 m_pImpl->m_aResults.push_back(
474 new ResultListEntry( pContentProperties ) );
477 catch ( DAVException const & )
482 m_pImpl->m_bCountFinal = true;
484 // Callback possible, because listeners may be informed!
485 aGuard.clear();
486 getResultSet()->rowCountFinal();
488 return !m_pImpl->m_bThrowException;
491 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */