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 /**************************************************************************
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
;
55 // struct ResultListEntry.
59 struct ResultListEntry
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
)
78 typedef boost::ptr_vector
<ResultListEntry
> ResultList
;
82 // struct DataSupplier_Impl.
86 struct DataSupplier_Impl
89 ResultList m_aResults
;
90 rtl::Reference
< Content
> m_xContent
;
91 uno::Reference
< uno::XComponentContext
> m_xContext
;
92 sal_Int32 m_nOpenMode
;
94 bool m_bThrowException
;
97 const uno::Reference
< uno::XComponentContext
>& rxContext
,
98 const rtl::Reference
< Content
>& rContent
,
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
) )
124 DataSupplier::~DataSupplier()
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() )
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() )
154 aId
+= props
.getEscapedTitle();
156 if ( props
.isTrailingSlash() )
159 m_pImpl
->m_aResults
[ nIndex
].aId
= aId
;
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
;
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
;
191 return uno::Reference
< ucb::XContentIdentifier
>();
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
;
212 uno::Reference
< ucb::XContentIdentifier
> xId
213 = queryContentIdentifier( nIndex
);
218 uno::Reference
< ucb::XContent
> xContent
219 = m_pImpl
->m_xContent
->getProvider()->queryContent( xId
);
220 m_pImpl
->m_aResults
[ nIndex
].xContent
= xContent
;
224 catch ( ucb::IllegalIdentifierException
& )
228 return uno::Reference
< ucb::XContent
>();
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.
246 if ( m_pImpl
->m_aResults
.size() > nIndex
)
248 // Result already present.
258 sal_uInt32
DataSupplier::totalCount()
263 return m_pImpl
->m_aResults
.size();
268 sal_uInt32
DataSupplier::currentCount()
270 return m_pImpl
->m_aResults
.size();
275 bool DataSupplier::isCountFinal()
277 return m_pImpl
->m_bCountFinal
;
282 uno::Reference
< sdbc::XRow
> DataSupplier::queryPropertyValues(
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
;
297 if ( getResult( nIndex
) )
299 uno::Reference
< sdbc::XRow
> xRow
300 = Content::getPropertyValues(
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
;
311 return uno::Reference
< sdbc::XRow
>();
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
>();
326 void DataSupplier::close()
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();
361 if ( (*it
).equals( DAVProperties::RESOURCETYPE
) )
368 propertyNames
.push_back( DAVProperties::RESOURCETYPE
);
370 std::vector
< DAVResource
> resources
;
373 // propfind depth 1, get property values for parent AND for each
375 m_pImpl
->m_xContent
->getResourceAccess()
379 getResultSet()->getEnvironment() );
381 catch ( DAVException
& )
383 // OSL_FAIL( "PROPFIND : DAVException" );
384 m_pImpl
->m_bThrowException
= true;
387 if ( !m_pImpl
->m_bThrowException
)
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
411 NeonUri
aCurrURI( rRes
.uri
);
412 OUString aCurrPath
= aCurrURI
.GetPath();
413 if ( aCurrPath
.endsWith("/") )
417 aCurrPath
.getLength() - 1 );
419 aCurrPath
= NeonUri::unescape( aCurrPath
);
420 if ( aPath
== aCurrPath
)
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" ) );
453 case ucb::OpenMode::DOCUMENTS
:
455 bool bDocument
= false;
457 const uno::Any
& rValue
458 = pContentProperties
->getValue(
459 OUString( "IsDocument" ) );
460 rValue
>>= bDocument
;
468 case ucb::OpenMode::ALL
:
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!
486 getResultSet()->rowCountFinal();
488 return !m_pImpl
->m_bThrowException
;
491 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */