merge the formfield patch from ooo-build
[ooovba.git] / ucb / source / ucp / webdav / webdavdatasupplier.cxx
blobd36867da6e1141182bc511cc86eb0c83e343dfbc
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: webdavdatasupplier.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
34 /**************************************************************************
35 TODO
36 **************************************************************************
38 *************************************************************************/
39 #include <osl/diagnose.h>
40 #include <com/sun/star/ucb/OpenMode.hpp>
41 #include <ucbhelper/contentidentifier.hxx>
42 #include <ucbhelper/providerhelper.hxx>
43 #include "webdavdatasupplier.hxx"
44 #include "webdavcontent.hxx"
45 #include "ContentProperties.hxx"
46 #ifndef _WEBDAV_SESSION_HXX
47 #include "DAVSession.hxx"
48 #endif
49 #include "NeonUri.hxx"
51 using namespace com::sun::star;
52 using namespace webdav_ucp;
54 namespace webdav_ucp
57 //=========================================================================
59 // struct ResultListEntry.
61 //=========================================================================
63 struct ResultListEntry
65 rtl::OUString aId;
66 uno::Reference< ucb::XContentIdentifier > xId;
67 uno::Reference< ucb::XContent > xContent;
68 uno::Reference< sdbc::XRow > xRow;
69 const ContentProperties* pData;
71 ResultListEntry( const ContentProperties* pEntry ) : pData( pEntry ) {};
72 ~ResultListEntry() { delete pData; }
75 //=========================================================================
77 // ResultList.
79 //=========================================================================
81 typedef std::vector< ResultListEntry* > ResultList;
83 //=========================================================================
85 // struct DataSupplier_Impl.
87 //=========================================================================
89 struct DataSupplier_Impl
91 osl::Mutex m_aMutex;
92 ResultList m_aResults;
93 rtl::Reference< Content > m_xContent;
94 uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
95 sal_Int32 m_nOpenMode;
96 sal_Bool m_bCountFinal;
97 sal_Bool m_bThrowException;
99 DataSupplier_Impl(
100 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
101 const rtl::Reference< Content >& rContent,
102 sal_Int32 nOpenMode )
103 : m_xContent( rContent ), m_xSMgr( rxSMgr ), m_nOpenMode( nOpenMode ),
104 m_bCountFinal( sal_False ), m_bThrowException( sal_False ) {}
105 ~DataSupplier_Impl();
108 //=========================================================================
109 DataSupplier_Impl::~DataSupplier_Impl()
111 ResultList::const_iterator it = m_aResults.begin();
112 ResultList::const_iterator end = m_aResults.end();
114 while ( it != end )
116 delete (*it);
117 it++;
123 //=========================================================================
124 //=========================================================================
126 // DataSupplier Implementation.
128 //=========================================================================
129 //=========================================================================
131 DataSupplier::DataSupplier(
132 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
133 const rtl::Reference< Content >& rContent,
134 sal_Int32 nOpenMode )
135 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
139 //=========================================================================
140 // virtual
141 DataSupplier::~DataSupplier()
143 delete m_pImpl;
146 //=========================================================================
147 // virtual
148 rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
150 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
152 if ( nIndex < m_pImpl->m_aResults.size() )
154 rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
155 if ( aId.getLength() )
157 // Already cached.
158 return aId;
162 if ( getResult( nIndex ) )
164 rtl::OUString aId = m_pImpl->m_xContent->getResourceAccess().getURL();
166 const ContentProperties& props
167 = *( m_pImpl->m_aResults[ nIndex ]->pData );
169 if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
170 aId += rtl::OUString::createFromAscii( "/" );
172 aId += props.getEscapedTitle();
174 if ( props.isTrailingSlash() )
175 aId += rtl::OUString::createFromAscii( "/" );
177 m_pImpl->m_aResults[ nIndex ]->aId = aId;
178 return aId;
180 return rtl::OUString();
183 //=========================================================================
184 // virtual
185 uno::Reference< ucb::XContentIdentifier >
186 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
188 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
190 if ( nIndex < m_pImpl->m_aResults.size() )
192 uno::Reference< ucb::XContentIdentifier > xId
193 = m_pImpl->m_aResults[ nIndex ]->xId;
194 if ( xId.is() )
196 // Already cached.
197 return xId;
201 rtl::OUString aId = queryContentIdentifierString( nIndex );
202 if ( aId.getLength() )
204 uno::Reference< ucb::XContentIdentifier > xId
205 = new ::ucbhelper::ContentIdentifier( aId );
206 m_pImpl->m_aResults[ nIndex ]->xId = xId;
207 return xId;
209 return uno::Reference< ucb::XContentIdentifier >();
212 //=========================================================================
213 // virtual
214 uno::Reference< ucb::XContent >
215 DataSupplier::queryContent( sal_uInt32 nIndex )
217 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
219 if ( nIndex < m_pImpl->m_aResults.size() )
221 uno::Reference< ucb::XContent > xContent
222 = m_pImpl->m_aResults[ nIndex ]->xContent;
223 if ( xContent.is() )
225 // Already cached.
226 return xContent;
230 uno::Reference< ucb::XContentIdentifier > xId
231 = queryContentIdentifier( nIndex );
232 if ( xId.is() )
236 uno::Reference< ucb::XContent > xContent
237 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
238 m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
239 return xContent;
242 catch ( ucb::IllegalIdentifierException& )
246 return uno::Reference< ucb::XContent >();
249 //=========================================================================
250 // virtual
251 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
253 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
255 if ( m_pImpl->m_aResults.size() > nIndex )
257 // Result already present.
258 return sal_True;
261 // Obtain values...
262 if ( getData() )
264 if ( m_pImpl->m_aResults.size() > nIndex )
266 // Result already present.
267 return sal_True;
271 return sal_False;
274 //=========================================================================
275 // virtual
276 sal_uInt32 DataSupplier::totalCount()
278 // Obtain values...
279 getData();
281 return m_pImpl->m_aResults.size();
284 //=========================================================================
285 // virtual
286 sal_uInt32 DataSupplier::currentCount()
288 return m_pImpl->m_aResults.size();
291 //=========================================================================
292 // virtual
293 sal_Bool DataSupplier::isCountFinal()
295 return m_pImpl->m_bCountFinal;
298 //=========================================================================
299 // virtual
300 uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues(
301 sal_uInt32 nIndex )
303 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
305 if ( nIndex < m_pImpl->m_aResults.size() )
307 uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
308 if ( xRow.is() )
310 // Already cached.
311 return xRow;
315 if ( getResult( nIndex ) )
317 uno::Reference< sdbc::XRow > xRow
318 = Content::getPropertyValues(
319 m_pImpl->m_xSMgr,
320 getResultSet()->getProperties(),
321 *(m_pImpl->m_aResults[ nIndex ]->pData),
322 rtl::Reference< ::ucbhelper::ContentProviderImplHelper >(
323 m_pImpl->m_xContent->getProvider().get() ),
324 queryContentIdentifierString( nIndex ) );
325 m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
326 return xRow;
329 return uno::Reference< sdbc::XRow >();
332 //=========================================================================
333 // virtual
334 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
336 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
338 if ( nIndex < m_pImpl->m_aResults.size() )
339 m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
342 //=========================================================================
343 // virtual
344 void DataSupplier::close()
348 //=========================================================================
349 // virtual
350 void DataSupplier::validate()
351 throw( ucb::ResultSetException )
353 if ( m_pImpl->m_bThrowException )
354 throw ucb::ResultSetException();
357 //=========================================================================
358 sal_Bool DataSupplier::getData()
360 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
362 if ( !m_pImpl->m_bCountFinal )
364 std::vector< rtl::OUString > propertyNames;
365 ContentProperties::UCBNamesToDAVNames(
366 getResultSet()->getProperties(), propertyNames );
368 // Append "resourcetype", if not already present. It's value is
369 // needed to get a valid ContentProperties::pIsFolder value, which
370 // is needed for OpenMode handling.
372 std::vector< rtl::OUString >::const_iterator it
373 = propertyNames.begin();
374 std::vector< rtl::OUString >::const_iterator end
375 = propertyNames.end();
377 while ( it != end )
379 if ( (*it).equals( DAVProperties::RESOURCETYPE ) )
380 break;
382 it++;
385 if ( it == end )
386 propertyNames.push_back( DAVProperties::RESOURCETYPE );
388 std::vector< DAVResource > resources;
391 // propfind depth 1, get property values for parent AND for each
392 // child
393 m_pImpl->m_xContent->getResourceAccess()
394 .PROPFIND( DAVONE,
395 propertyNames,
396 resources,
397 getResultSet()->getEnvironment() );
399 catch ( DAVException & )
401 // OSL_ENSURE( sal_False, "PROPFIND : DAVException" );
402 m_pImpl->m_bThrowException = sal_True;
405 if ( !m_pImpl->m_bThrowException )
409 NeonUri aURI(
410 m_pImpl->m_xContent->getResourceAccess().getURL() );
411 rtl::OUString aPath = aURI.GetPath();
413 if ( aPath.getStr()[ aPath.getLength() - 1 ]
414 == sal_Unicode( '/' ) )
415 aPath = aPath.copy( 0, aPath.getLength() - 1 );
417 aPath = NeonUri::unescape( aPath );
418 bool bFoundParent = false;
420 for ( sal_uInt32 n = 0; n < resources.size(); ++n )
422 const DAVResource & rRes = resources[ n ];
424 // Filter parent, which is contained somewhere(!) in
425 // the vector.
426 if ( !bFoundParent )
430 NeonUri aCurrURI( rRes.uri );
431 rtl::OUString aCurrPath = aCurrURI.GetPath();
432 if ( aCurrPath.getStr()[
433 aCurrPath.getLength() - 1 ]
434 == sal_Unicode( '/' ) )
435 aCurrPath
436 = aCurrPath.copy(
438 aCurrPath.getLength() - 1 );
440 aCurrPath = NeonUri::unescape( aCurrPath );
441 if ( aPath == aCurrPath )
443 bFoundParent = true;
444 continue;
447 catch ( DAVException const & )
449 // do nothing, ignore error. continue.
453 ContentProperties* pContentProperties
454 = new ContentProperties( rRes );
456 // Check resource against open mode.
457 switch ( m_pImpl->m_nOpenMode )
459 case ucb::OpenMode::FOLDERS:
461 sal_Bool bFolder = sal_False;
463 const uno::Any & rValue
464 = pContentProperties->getValue(
465 rtl::OUString(
466 RTL_CONSTASCII_USTRINGPARAM(
467 "IsFolder" ) ) );
468 rValue >>= bFolder;
470 if ( !bFolder )
471 continue;
473 break;
476 case ucb::OpenMode::DOCUMENTS:
478 sal_Bool bDocument = sal_False;
480 const uno::Any & rValue
481 = pContentProperties->getValue(
482 rtl::OUString(
483 RTL_CONSTASCII_USTRINGPARAM(
484 "IsDocument" ) ) );
485 rValue >>= bDocument;
487 if ( !bDocument )
488 continue;
490 break;
493 case ucb::OpenMode::ALL:
494 default:
495 break;
498 m_pImpl->m_aResults.push_back(
499 new ResultListEntry( pContentProperties ) );
502 catch ( DAVException const & )
507 m_pImpl->m_bCountFinal = sal_True;
509 // Callback possible, because listeners may be informed!
510 aGuard.clear();
511 getResultSet()->rowCountFinal();
513 return !m_pImpl->m_bThrowException;