1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: webdavdatasupplier.cxx,v $
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 /**************************************************************************
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"
49 #include "NeonUri.hxx"
51 using namespace com::sun::star
;
52 using namespace webdav_ucp
;
57 //=========================================================================
59 // struct ResultListEntry.
61 //=========================================================================
63 struct ResultListEntry
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 //=========================================================================
79 //=========================================================================
81 typedef std::vector
< ResultListEntry
* > ResultList
;
83 //=========================================================================
85 // struct DataSupplier_Impl.
87 //=========================================================================
89 struct DataSupplier_Impl
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
;
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();
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 //=========================================================================
141 DataSupplier::~DataSupplier()
146 //=========================================================================
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() )
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
;
180 return rtl::OUString();
183 //=========================================================================
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
;
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
;
209 return uno::Reference
< ucb::XContentIdentifier
>();
212 //=========================================================================
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
;
230 uno::Reference
< ucb::XContentIdentifier
> xId
231 = queryContentIdentifier( nIndex
);
236 uno::Reference
< ucb::XContent
> xContent
237 = m_pImpl
->m_xContent
->getProvider()->queryContent( xId
);
238 m_pImpl
->m_aResults
[ nIndex
]->xContent
= xContent
;
242 catch ( ucb::IllegalIdentifierException
& )
246 return uno::Reference
< ucb::XContent
>();
249 //=========================================================================
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.
264 if ( m_pImpl
->m_aResults
.size() > nIndex
)
266 // Result already present.
274 //=========================================================================
276 sal_uInt32
DataSupplier::totalCount()
281 return m_pImpl
->m_aResults
.size();
284 //=========================================================================
286 sal_uInt32
DataSupplier::currentCount()
288 return m_pImpl
->m_aResults
.size();
291 //=========================================================================
293 sal_Bool
DataSupplier::isCountFinal()
295 return m_pImpl
->m_bCountFinal
;
298 //=========================================================================
300 uno::Reference
< sdbc::XRow
> DataSupplier::queryPropertyValues(
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
;
315 if ( getResult( nIndex
) )
317 uno::Reference
< sdbc::XRow
> xRow
318 = Content::getPropertyValues(
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
;
329 return uno::Reference
< sdbc::XRow
>();
332 //=========================================================================
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 //=========================================================================
344 void DataSupplier::close()
348 //=========================================================================
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();
379 if ( (*it
).equals( DAVProperties::RESOURCETYPE
) )
386 propertyNames
.push_back( DAVProperties::RESOURCETYPE
);
388 std::vector
< DAVResource
> resources
;
391 // propfind depth 1, get property values for parent AND for each
393 m_pImpl
->m_xContent
->getResourceAccess()
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
)
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
430 NeonUri
aCurrURI( rRes
.uri
);
431 rtl::OUString aCurrPath
= aCurrURI
.GetPath();
432 if ( aCurrPath
.getStr()[
433 aCurrPath
.getLength() - 1 ]
434 == sal_Unicode( '/' ) )
438 aCurrPath
.getLength() - 1 );
440 aCurrPath
= NeonUri::unescape( aCurrPath
);
441 if ( aPath
== aCurrPath
)
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(
466 RTL_CONSTASCII_USTRINGPARAM(
476 case ucb::OpenMode::DOCUMENTS
:
478 sal_Bool bDocument
= sal_False
;
480 const uno::Any
& rValue
481 = pContentProperties
->getValue(
483 RTL_CONSTASCII_USTRINGPARAM(
485 rValue
>>= bDocument
;
493 case ucb::OpenMode::ALL
:
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!
511 getResultSet()->rowCountFinal();
513 return !m_pImpl
->m_bThrowException
;