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 #ifndef _WEBDAV_SESSION_HXX
28 #include "DAVSession.hxx"
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
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 //=========================================================================
60 //=========================================================================
62 typedef std::vector
< ResultListEntry
* > ResultList
;
64 //=========================================================================
66 // struct DataSupplier_Impl.
68 //=========================================================================
70 struct DataSupplier_Impl
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
;
81 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
82 const rtl::Reference
< Content
>& rContent
,
84 : m_xContent( rContent
), m_xSMgr( rxSMgr
), m_nOpenMode( nOpenMode
),
85 m_bCountFinal( sal_False
), m_bThrowException( sal_False
) {}
89 //=========================================================================
90 DataSupplier_Impl::~DataSupplier_Impl()
92 ResultList::const_iterator it
= m_aResults
.begin();
93 ResultList::const_iterator end
= m_aResults
.end();
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 //=========================================================================
122 DataSupplier::~DataSupplier()
127 //=========================================================================
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() )
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
;
161 return rtl::OUString();
164 //=========================================================================
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
;
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
;
190 return uno::Reference
< ucb::XContentIdentifier
>();
193 //=========================================================================
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
;
211 uno::Reference
< ucb::XContentIdentifier
> xId
212 = queryContentIdentifier( nIndex
);
217 uno::Reference
< ucb::XContent
> xContent
218 = m_pImpl
->m_xContent
->getProvider()->queryContent( xId
);
219 m_pImpl
->m_aResults
[ nIndex
]->xContent
= xContent
;
223 catch ( ucb::IllegalIdentifierException
& )
227 return uno::Reference
< ucb::XContent
>();
230 //=========================================================================
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.
245 if ( m_pImpl
->m_aResults
.size() > nIndex
)
247 // Result already present.
255 //=========================================================================
257 sal_uInt32
DataSupplier::totalCount()
262 return m_pImpl
->m_aResults
.size();
265 //=========================================================================
267 sal_uInt32
DataSupplier::currentCount()
269 return m_pImpl
->m_aResults
.size();
272 //=========================================================================
274 sal_Bool
DataSupplier::isCountFinal()
276 return m_pImpl
->m_bCountFinal
;
279 //=========================================================================
281 uno::Reference
< sdbc::XRow
> DataSupplier::queryPropertyValues(
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
;
296 if ( getResult( nIndex
) )
298 uno::Reference
< sdbc::XRow
> xRow
299 = Content::getPropertyValues(
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
;
310 return uno::Reference
< sdbc::XRow
>();
313 //=========================================================================
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 //=========================================================================
325 void DataSupplier::close()
329 //=========================================================================
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();
360 if ( (*it
).equals( DAVProperties::RESOURCETYPE
) )
367 propertyNames
.push_back( DAVProperties::RESOURCETYPE
);
369 std::vector
< DAVResource
> resources
;
372 // propfind depth 1, get property values for parent AND for each
374 m_pImpl
->m_xContent
->getResourceAccess()
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
)
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
411 SerfUri
aCurrURI( rRes
.uri
);
412 rtl::OUString aCurrPath
= aCurrURI
.GetPath();
413 if ( aCurrPath
.getStr()[
414 aCurrPath
.getLength() - 1 ]
415 == sal_Unicode( '/' ) )
419 aCurrPath
.getLength() - 1 );
421 aCurrPath
= SerfUri::unescape( aCurrPath
);
422 if ( aPath
== aCurrPath
)
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(
447 RTL_CONSTASCII_USTRINGPARAM(
457 case ucb::OpenMode::DOCUMENTS
:
459 sal_Bool bDocument
= sal_False
;
461 const uno::Any
& rValue
462 = pContentProperties
->getValue(
464 RTL_CONSTASCII_USTRINGPARAM(
466 rValue
>>= bDocument
;
474 case ucb::OpenMode::ALL
:
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!
492 getResultSet()->rowCountFinal();
494 return !m_pImpl
->m_bThrowException
;
497 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */