Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : /**************************************************************************
31 : : TODO
32 : : **************************************************************************
33 : :
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"
44 : :
45 : : using namespace com::sun::star;
46 : : using namespace webdav_ucp;
47 : :
48 : : namespace webdav_ucp
49 : : {
50 : :
51 : : //=========================================================================
52 : : //
53 : : // struct ResultListEntry.
54 : : //
55 : : //=========================================================================
56 : :
57 : : struct ResultListEntry
58 : : {
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;
64 : :
65 : 0 : ResultListEntry( const ContentProperties* pEntry ) : pData( pEntry ) {};
66 [ # # ][ # # ]: 0 : ~ResultListEntry() { delete pData; }
67 : : };
68 : :
69 : : //=========================================================================
70 : : //
71 : : // ResultList.
72 : : //
73 : : //=========================================================================
74 : :
75 : : typedef std::vector< ResultListEntry* > ResultList;
76 : :
77 : : //=========================================================================
78 : : //
79 : : // struct DataSupplier_Impl.
80 : : //
81 : : //=========================================================================
82 : :
83 : : struct DataSupplier_Impl
84 : : {
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;
92 : :
93 : 0 : 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 [ # # ]: 0 : m_bCountFinal( sal_False ), m_bThrowException( sal_False ) {}
99 : : ~DataSupplier_Impl();
100 : : };
101 : :
102 : : //=========================================================================
103 : 0 : DataSupplier_Impl::~DataSupplier_Impl()
104 : : {
105 [ # # ]: 0 : ResultList::const_iterator it = m_aResults.begin();
106 [ # # ]: 0 : ResultList::const_iterator end = m_aResults.end();
107 : :
108 [ # # ][ # # ]: 0 : while ( it != end )
109 : : {
110 [ # # ][ # # ]: 0 : delete (*it);
111 : 0 : ++it;
112 : : }
113 : 0 : }
114 : :
115 : : }
116 : :
117 : : //=========================================================================
118 : : //=========================================================================
119 : : //
120 : : // DataSupplier Implementation.
121 : : //
122 : : //=========================================================================
123 : : //=========================================================================
124 : :
125 : 0 : DataSupplier::DataSupplier(
126 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
127 : : const rtl::Reference< Content >& rContent,
128 : : sal_Int32 nOpenMode )
129 [ # # ][ # # ]: 0 : : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
130 : : {
131 : 0 : }
132 : :
133 : : //=========================================================================
134 : : // virtual
135 : 0 : DataSupplier::~DataSupplier()
136 : : {
137 [ # # ][ # # ]: 0 : delete m_pImpl;
138 [ # # ]: 0 : }
139 : :
140 : : //=========================================================================
141 : : // virtual
142 : 0 : rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
143 : : {
144 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
145 : :
146 [ # # ]: 0 : if ( nIndex < m_pImpl->m_aResults.size() )
147 : : {
148 : 0 : rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
149 [ # # ]: 0 : if ( !aId.isEmpty() )
150 : : {
151 : : // Already cached.
152 : 0 : return aId;
153 [ # # ]: 0 : }
154 : : }
155 : :
156 [ # # ][ # # ]: 0 : if ( getResult( nIndex ) )
157 : : {
158 : 0 : rtl::OUString aId = m_pImpl->m_xContent->getResourceAccess().getURL();
159 : :
160 : : const ContentProperties& props
161 : 0 : = *( m_pImpl->m_aResults[ nIndex ]->pData );
162 : :
163 [ # # ]: 0 : if ( ( aId.lastIndexOf( '/' ) + 1 ) != aId.getLength() )
164 : 0 : aId += rtl::OUString("/");
165 : :
166 : 0 : aId += props.getEscapedTitle();
167 : :
168 [ # # ]: 0 : if ( props.isTrailingSlash() )
169 : 0 : aId += rtl::OUString("/");
170 : :
171 : 0 : m_pImpl->m_aResults[ nIndex ]->aId = aId;
172 : 0 : return aId;
173 : : }
174 [ # # ]: 0 : return rtl::OUString();
175 : : }
176 : :
177 : : //=========================================================================
178 : : // virtual
179 : : uno::Reference< ucb::XContentIdentifier >
180 : 0 : DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
181 : : {
182 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
183 : :
184 [ # # ]: 0 : if ( nIndex < m_pImpl->m_aResults.size() )
185 : : {
186 : : uno::Reference< ucb::XContentIdentifier > xId
187 : 0 : = m_pImpl->m_aResults[ nIndex ]->xId;
188 [ # # ]: 0 : if ( xId.is() )
189 : : {
190 : : // Already cached.
191 : 0 : return xId;
192 [ # # ]: 0 : }
193 : : }
194 : :
195 [ # # ]: 0 : rtl::OUString aId = queryContentIdentifierString( nIndex );
196 [ # # ]: 0 : if ( !aId.isEmpty() )
197 : : {
198 : : uno::Reference< ucb::XContentIdentifier > xId
199 [ # # ][ # # ]: 0 : = new ::ucbhelper::ContentIdentifier( aId );
[ # # ]
200 [ # # ]: 0 : m_pImpl->m_aResults[ nIndex ]->xId = xId;
201 : 0 : return xId;
202 : : }
203 [ # # ]: 0 : return uno::Reference< ucb::XContentIdentifier >();
204 : : }
205 : :
206 : : //=========================================================================
207 : : // virtual
208 : : uno::Reference< ucb::XContent >
209 : 0 : DataSupplier::queryContent( sal_uInt32 nIndex )
210 : : {
211 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
212 : :
213 [ # # ]: 0 : if ( nIndex < m_pImpl->m_aResults.size() )
214 : : {
215 : : uno::Reference< ucb::XContent > xContent
216 : 0 : = m_pImpl->m_aResults[ nIndex ]->xContent;
217 [ # # ]: 0 : if ( xContent.is() )
218 : : {
219 : : // Already cached.
220 : 0 : return xContent;
221 [ # # ]: 0 : }
222 : : }
223 : :
224 : : uno::Reference< ucb::XContentIdentifier > xId
225 [ # # ]: 0 : = queryContentIdentifier( nIndex );
226 [ # # ]: 0 : if ( xId.is() )
227 : : {
228 : : try
229 : : {
230 : : uno::Reference< ucb::XContent > xContent
231 [ # # ]: 0 : = m_pImpl->m_xContent->getProvider()->queryContent( xId );
232 [ # # ]: 0 : m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
233 [ # # ]: 0 : return xContent;
234 : :
235 : : }
236 [ # # ]: 0 : catch ( ucb::IllegalIdentifierException& )
237 : : {
238 : : }
239 : : }
240 [ # # ]: 0 : return uno::Reference< ucb::XContent >();
241 : : }
242 : :
243 : : //=========================================================================
244 : : // virtual
245 : 0 : sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
246 : : {
247 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
248 : :
249 [ # # ]: 0 : if ( m_pImpl->m_aResults.size() > nIndex )
250 : : {
251 : : // Result already present.
252 : 0 : return sal_True;
253 : : }
254 : :
255 : : // Obtain values...
256 [ # # ][ # # ]: 0 : if ( getData() )
257 : : {
258 [ # # ]: 0 : if ( m_pImpl->m_aResults.size() > nIndex )
259 : : {
260 : : // Result already present.
261 : 0 : return sal_True;
262 : : }
263 : : }
264 : :
265 [ # # ]: 0 : return sal_False;
266 : : }
267 : :
268 : : //=========================================================================
269 : : // virtual
270 : 0 : sal_uInt32 DataSupplier::totalCount()
271 : : {
272 : : // Obtain values...
273 : 0 : getData();
274 : :
275 : 0 : return m_pImpl->m_aResults.size();
276 : : }
277 : :
278 : : //=========================================================================
279 : : // virtual
280 : 0 : sal_uInt32 DataSupplier::currentCount()
281 : : {
282 : 0 : return m_pImpl->m_aResults.size();
283 : : }
284 : :
285 : : //=========================================================================
286 : : // virtual
287 : 0 : sal_Bool DataSupplier::isCountFinal()
288 : : {
289 : 0 : return m_pImpl->m_bCountFinal;
290 : : }
291 : :
292 : : //=========================================================================
293 : : // virtual
294 : 0 : uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues(
295 : : sal_uInt32 nIndex )
296 : : {
297 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
298 : :
299 [ # # ]: 0 : if ( nIndex < m_pImpl->m_aResults.size() )
300 : : {
301 : 0 : uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
302 [ # # ]: 0 : if ( xRow.is() )
303 : : {
304 : : // Already cached.
305 : 0 : return xRow;
306 [ # # ]: 0 : }
307 : : }
308 : :
309 [ # # ][ # # ]: 0 : if ( getResult( nIndex ) )
310 : : {
311 : : uno::Reference< sdbc::XRow > xRow
312 : : = Content::getPropertyValues(
313 : : m_pImpl->m_xSMgr,
314 [ # # ][ # # ]: 0 : getResultSet()->getProperties(),
315 : 0 : *(m_pImpl->m_aResults[ nIndex ]->pData),
316 : : rtl::Reference< ::ucbhelper::ContentProviderImplHelper >(
317 : 0 : m_pImpl->m_xContent->getProvider().get() ),
318 [ # # ][ # # ]: 0 : queryContentIdentifierString( nIndex ) );
319 [ # # ]: 0 : m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
320 : 0 : return xRow;
321 : : }
322 : :
323 [ # # ]: 0 : return uno::Reference< sdbc::XRow >();
324 : : }
325 : :
326 : : //=========================================================================
327 : : // virtual
328 : 0 : void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
329 : : {
330 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
331 : :
332 [ # # ]: 0 : if ( nIndex < m_pImpl->m_aResults.size() )
333 [ # # ][ # # ]: 0 : m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
334 : 0 : }
335 : :
336 : : //=========================================================================
337 : : // virtual
338 : 0 : void DataSupplier::close()
339 : : {
340 : 0 : }
341 : :
342 : : //=========================================================================
343 : : // virtual
344 : 0 : void DataSupplier::validate()
345 : : throw( ucb::ResultSetException )
346 : : {
347 [ # # ]: 0 : if ( m_pImpl->m_bThrowException )
348 [ # # ]: 0 : throw ucb::ResultSetException();
349 : 0 : }
350 : :
351 : : //=========================================================================
352 : 0 : sal_Bool DataSupplier::getData()
353 : : {
354 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
355 : :
356 [ # # ]: 0 : if ( !m_pImpl->m_bCountFinal )
357 : : {
358 [ # # ]: 0 : std::vector< rtl::OUString > propertyNames;
359 : : ContentProperties::UCBNamesToDAVNames(
360 [ # # ][ # # ]: 0 : getResultSet()->getProperties(), propertyNames );
[ # # ]
361 : :
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.
365 : :
366 : : std::vector< rtl::OUString >::const_iterator it
367 [ # # ]: 0 : = propertyNames.begin();
368 : : std::vector< rtl::OUString >::const_iterator end
369 [ # # ]: 0 : = propertyNames.end();
370 : :
371 [ # # ][ # # ]: 0 : while ( it != end )
372 : : {
373 [ # # ]: 0 : if ( (*it).equals( DAVProperties::RESOURCETYPE ) )
374 : 0 : break;
375 : :
376 : 0 : ++it;
377 : : }
378 : :
379 [ # # ][ # # ]: 0 : if ( it == end )
380 [ # # ]: 0 : propertyNames.push_back( DAVProperties::RESOURCETYPE );
381 : :
382 [ # # ]: 0 : std::vector< DAVResource > resources;
383 : : try
384 : : {
385 : : // propfind depth 1, get property values for parent AND for each
386 : : // child
387 : 0 : m_pImpl->m_xContent->getResourceAccess()
388 : : .PROPFIND( DAVONE,
389 : : propertyNames,
390 : : resources,
391 [ # # ]: 0 : getResultSet()->getEnvironment() );
[ # # # # ]
[ # # ]
392 : : }
393 : 0 : catch ( DAVException & )
394 : : {
395 : : // OSL_FAIL( "PROPFIND : DAVException" );
396 : 0 : m_pImpl->m_bThrowException = sal_True;
397 : : }
398 : :
399 [ # # ]: 0 : if ( !m_pImpl->m_bThrowException )
400 : : {
401 : : try
402 : : {
403 : : NeonUri aURI(
404 [ # # ]: 0 : m_pImpl->m_xContent->getResourceAccess().getURL() );
405 : 0 : rtl::OUString aPath = aURI.GetPath();
406 : :
407 [ # # ]: 0 : if ( aPath.getStr()[ aPath.getLength() - 1 ]
408 : : == sal_Unicode( '/' ) )
409 : 0 : aPath = aPath.copy( 0, aPath.getLength() - 1 );
410 : :
411 [ # # ]: 0 : aPath = NeonUri::unescape( aPath );
412 : 0 : bool bFoundParent = false;
413 : :
414 [ # # ]: 0 : for ( sal_uInt32 n = 0; n < resources.size(); ++n )
415 : : {
416 : 0 : const DAVResource & rRes = resources[ n ];
417 : :
418 : : // Filter parent, which is contained somewhere(!) in
419 : : // the vector.
420 [ # # ]: 0 : if ( !bFoundParent )
421 : : {
422 : : try
423 : : {
424 [ # # ]: 0 : NeonUri aCurrURI( rRes.uri );
425 : 0 : rtl::OUString aCurrPath = aCurrURI.GetPath();
426 [ # # ]: 0 : if ( aCurrPath.getStr()[
427 : 0 : aCurrPath.getLength() - 1 ]
428 : : == sal_Unicode( '/' ) )
429 : : aCurrPath
430 : : = aCurrPath.copy(
431 : : 0,
432 : 0 : aCurrPath.getLength() - 1 );
433 : :
434 [ # # ]: 0 : aCurrPath = NeonUri::unescape( aCurrPath );
435 [ # # ]: 0 : if ( aPath == aCurrPath )
436 : : {
437 : 0 : bFoundParent = true;
438 : 0 : continue;
439 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
440 : : }
441 : 0 : catch ( DAVException const & )
442 : : {
443 : : // do nothing, ignore error. continue.
444 : : }
445 : : }
446 : :
447 : : ContentProperties* pContentProperties
448 [ # # ][ # # ]: 0 : = new ContentProperties( rRes );
449 : :
450 : : // Check resource against open mode.
451 [ # # # ]: 0 : switch ( m_pImpl->m_nOpenMode )
452 : : {
453 : : case ucb::OpenMode::FOLDERS:
454 : : {
455 : 0 : sal_Bool bFolder = sal_False;
456 : :
457 : : const uno::Any & rValue
458 : : = pContentProperties->getValue(
459 [ # # ]: 0 : rtl::OUString( "IsFolder" ) );
460 : 0 : rValue >>= bFolder;
461 : :
462 [ # # ]: 0 : if ( !bFolder )
463 : 0 : continue;
464 : :
465 : : break;
466 : : }
467 : :
468 : : case ucb::OpenMode::DOCUMENTS:
469 : : {
470 : 0 : sal_Bool bDocument = sal_False;
471 : :
472 : : const uno::Any & rValue
473 : : = pContentProperties->getValue(
474 [ # # ]: 0 : rtl::OUString( "IsDocument" ) );
475 : 0 : rValue >>= bDocument;
476 : :
477 [ # # ]: 0 : if ( !bDocument )
478 : 0 : continue;
479 : :
480 : : break;
481 : : }
482 : :
483 : : case ucb::OpenMode::ALL:
484 : : default:
485 : 0 : break;
486 : : }
487 : :
488 : : m_pImpl->m_aResults.push_back(
489 [ # # ][ # # ]: 0 : new ResultListEntry( pContentProperties ) );
[ # # ]
490 [ # # ][ # # ]: 0 : }
491 : : }
492 : 0 : catch ( DAVException const & )
493 : : {
494 : : }
495 : : }
496 : :
497 : 0 : m_pImpl->m_bCountFinal = sal_True;
498 : :
499 : : // Callback possible, because listeners may be informed!
500 [ # # ]: 0 : aGuard.clear();
501 [ # # ][ # # ]: 0 : getResultSet()->rowCountFinal();
502 : : }
503 [ # # ]: 0 : return !m_pImpl->m_bThrowException;
504 : : }
505 : :
506 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|