1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 #include "DAVSession.hxx"
28 #include "SerfUri.hxx"
30 using namespace com::sun::star
;
31 using namespace http_dav_ucp
;
33 namespace http_dav_ucp
38 // struct ResultListEntry.
42 struct ResultListEntry
45 uno::Reference
< ucb::XContentIdentifier
> xId
;
46 uno::Reference
< ucb::XContent
> xContent
;
47 uno::Reference
< sdbc::XRow
> xRow
;
48 const ContentProperties
* pData
;
50 ResultListEntry( const ContentProperties
* pEntry
) : pData( pEntry
) {};
51 ~ResultListEntry() { delete pData
; }
60 typedef std::vector
< ResultListEntry
* > ResultList
;
64 // struct DataSupplier_Impl.
68 struct DataSupplier_Impl
71 ResultList m_aResults
;
72 rtl::Reference
< Content
> m_xContent
;
73 uno::Reference
< uno::XComponentContext
> m_xContext
;
74 sal_Int32 m_nOpenMode
;
76 bool m_bThrowException
;
79 const uno::Reference
< uno::XComponentContext
>& rxContext
,
80 const rtl::Reference
< Content
>& rContent
,
82 : m_xContent( rContent
), m_xContext( rxContext
), m_nOpenMode( nOpenMode
),
83 m_bCountFinal( false ), m_bThrowException( false ) {}
88 DataSupplier_Impl::~DataSupplier_Impl()
90 ResultList::const_iterator it
= m_aResults
.begin();
91 ResultList::const_iterator end
= m_aResults
.end();
105 // DataSupplier Implementation.
110 DataSupplier::DataSupplier(
111 const uno::Reference
< uno::XComponentContext
>& rxContext
,
112 const rtl::Reference
< Content
>& rContent
,
113 sal_Int32 nOpenMode
)
114 : m_pImpl( new DataSupplier_Impl( rxContext
, rContent
, nOpenMode
) )
120 DataSupplier::~DataSupplier()
127 OUString
DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex
)
129 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
131 if ( nIndex
< m_pImpl
->m_aResults
.size() )
133 OUString aId
= m_pImpl
->m_aResults
[ nIndex
]->aId
;
134 if ( aId
.getLength() )
141 if ( getResult( nIndex
) )
143 OUString aId
= m_pImpl
->m_xContent
->getResourceAccess().getURL();
145 const ContentProperties
& props
146 = *( m_pImpl
->m_aResults
[ nIndex
]->pData
);
148 if ( ( aId
.lastIndexOf( '/' ) + 1 ) != aId
.getLength() )
151 aId
+= props
.getEscapedTitle();
153 if ( props
.isTrailingSlash() )
156 m_pImpl
->m_aResults
[ nIndex
]->aId
= aId
;
164 uno::Reference
< ucb::XContentIdentifier
>
165 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex
)
167 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
169 if ( nIndex
< m_pImpl
->m_aResults
.size() )
171 uno::Reference
< ucb::XContentIdentifier
> xId
172 = m_pImpl
->m_aResults
[ nIndex
]->xId
;
180 OUString aId
= queryContentIdentifierString( nIndex
);
181 if ( aId
.getLength() )
183 uno::Reference
< ucb::XContentIdentifier
> xId
184 = new ::ucbhelper::ContentIdentifier( aId
);
185 m_pImpl
->m_aResults
[ nIndex
]->xId
= xId
;
188 return uno::Reference
< ucb::XContentIdentifier
>();
193 uno::Reference
< ucb::XContent
>
194 DataSupplier::queryContent( sal_uInt32 nIndex
)
196 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
198 if ( nIndex
< m_pImpl
->m_aResults
.size() )
200 uno::Reference
< ucb::XContent
> xContent
201 = m_pImpl
->m_aResults
[ nIndex
]->xContent
;
209 uno::Reference
< ucb::XContentIdentifier
> xId
210 = queryContentIdentifier( nIndex
);
215 uno::Reference
< ucb::XContent
> xContent
216 = m_pImpl
->m_xContent
->getProvider()->queryContent( xId
);
217 m_pImpl
->m_aResults
[ nIndex
]->xContent
= xContent
;
221 catch ( ucb::IllegalIdentifierException
& )
225 return uno::Reference
< ucb::XContent
>();
230 bool DataSupplier::getResult( sal_uInt32 nIndex
)
232 osl::ClearableGuard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
234 if ( m_pImpl
->m_aResults
.size() > nIndex
)
236 // Result already present.
243 if ( m_pImpl
->m_aResults
.size() > nIndex
)
245 // Result already present.
255 sal_uInt32
DataSupplier::totalCount()
260 return m_pImpl
->m_aResults
.size();
265 sal_uInt32
DataSupplier::currentCount()
267 return m_pImpl
->m_aResults
.size();
272 bool DataSupplier::isCountFinal()
274 return m_pImpl
->m_bCountFinal
;
279 uno::Reference
< sdbc::XRow
> DataSupplier::queryPropertyValues(
282 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
284 if ( nIndex
< m_pImpl
->m_aResults
.size() )
286 uno::Reference
< sdbc::XRow
> xRow
= m_pImpl
->m_aResults
[ nIndex
]->xRow
;
294 if ( getResult( nIndex
) )
296 uno::Reference
< sdbc::XRow
> xRow
297 = Content::getPropertyValues(
299 getResultSet()->getProperties(),
300 *(m_pImpl
->m_aResults
[ nIndex
]->pData
),
301 rtl::Reference
< ::ucbhelper::ContentProviderImplHelper
>(
302 m_pImpl
->m_xContent
->getProvider().get() ),
303 queryContentIdentifierString( nIndex
) );
304 m_pImpl
->m_aResults
[ nIndex
]->xRow
= xRow
;
308 return uno::Reference
< sdbc::XRow
>();
313 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex
)
315 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
317 if ( nIndex
< m_pImpl
->m_aResults
.size() )
318 m_pImpl
->m_aResults
[ nIndex
]->xRow
= uno::Reference
< sdbc::XRow
>();
323 void DataSupplier::close()
329 void DataSupplier::validate()
330 throw( ucb::ResultSetException
)
332 if ( m_pImpl
->m_bThrowException
)
333 throw ucb::ResultSetException();
336 bool DataSupplier::getData()
338 osl::ClearableGuard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
340 if ( !m_pImpl
->m_bCountFinal
)
342 std::vector
< OUString
> propertyNames
;
343 ContentProperties::UCBNamesToDAVNames(
344 getResultSet()->getProperties(), propertyNames
);
346 // Append "resourcetype", if not already present. It's value is
347 // needed to get a valid ContentProperties::pIsFolder value, which
348 // is needed for OpenMode handling.
350 std::vector
< OUString
>::const_iterator it
351 = propertyNames
.begin();
352 std::vector
< OUString
>::const_iterator end
353 = propertyNames
.end();
357 if ( (*it
).equals( DAVProperties::RESOURCETYPE
) )
364 propertyNames
.push_back( DAVProperties::RESOURCETYPE
);
366 std::vector
< DAVResource
> resources
;
369 // propfind depth 1, get property values for parent AND for each
371 m_pImpl
->m_xContent
->getResourceAccess()
375 getResultSet()->getEnvironment() );
377 catch ( DAVException
& )
379 SAL_WARN( "ucb.ucp.webdav", "PROPFIND : DAVException" );
380 m_pImpl
->m_bThrowException
= true;
383 if ( !m_pImpl
->m_bThrowException
)
388 m_pImpl
->m_xContent
->getResourceAccess().getURL() );
389 OUString aPath
= aURI
.GetPath();
391 if ( aPath
.endsWith("/") )
392 aPath
= aPath
.copy( 0, aPath
.getLength() - 1 );
394 aPath
= SerfUri::unescape( aPath
);
395 bool bFoundParent
= false;
397 for ( sal_uInt32 n
= 0; n
< resources
.size(); ++n
)
399 const DAVResource
& rRes
= resources
[ n
];
401 // Filter parent, which is contained somewhere(!) in
407 SerfUri
aCurrURI( rRes
.uri
);
408 OUString aCurrPath
= aCurrURI
.GetPath();
409 if ( aCurrPath
.endsWith("/") )
413 aCurrPath
.getLength() - 1 );
415 aCurrPath
= SerfUri::unescape( aCurrPath
);
416 if ( aPath
== aCurrPath
)
422 catch ( DAVException
const & )
424 // do nothing, ignore error. continue.
428 ContentProperties
* pContentProperties
429 = new 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(
450 case ucb::OpenMode::DOCUMENTS
:
452 bool bDocument
= false;
454 const uno::Any
& rValue
455 = pContentProperties
->getValue(
458 rValue
>>= bDocument
;
466 case ucb::OpenMode::ALL
:
471 m_pImpl
->m_aResults
.push_back(
472 new ResultListEntry( pContentProperties
) );
475 catch ( DAVException
const & )
480 m_pImpl
->m_bCountFinal
= true;
482 // Callback possible, because listeners may be informed!
484 getResultSet()->rowCountFinal();
486 return !m_pImpl
->m_bThrowException
;
489 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */