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 <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"
45 using namespace com::sun::star
;
46 using namespace webdav_ucp
;
51 //=========================================================================
53 // struct ResultListEntry.
55 //=========================================================================
57 struct ResultListEntry
60 uno::Reference
< ucb::XContentIdentifier
> xId
;
61 uno::Reference
< ucb::XContent
> xContent
;
62 uno::Reference
< sdbc::XRow
> xRow
;
63 const ContentProperties
* pData
;
65 ResultListEntry( const ContentProperties
* pEntry
) : pData( pEntry
) {};
66 ~ResultListEntry() { delete pData
; }
69 //=========================================================================
73 //=========================================================================
75 typedef std::vector
< ResultListEntry
* > ResultList
;
77 //=========================================================================
79 // struct DataSupplier_Impl.
81 //=========================================================================
83 struct DataSupplier_Impl
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
;
94 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
95 const rtl::Reference
< Content
>& rContent
,
97 : m_xContent( rContent
), m_xSMgr( rxSMgr
), m_nOpenMode( nOpenMode
),
98 m_bCountFinal( sal_False
), m_bThrowException( sal_False
) {}
102 //=========================================================================
103 DataSupplier_Impl::~DataSupplier_Impl()
105 ResultList::const_iterator it
= m_aResults
.begin();
106 ResultList::const_iterator end
= m_aResults
.end();
117 //=========================================================================
118 //=========================================================================
120 // DataSupplier Implementation.
122 //=========================================================================
123 //=========================================================================
125 DataSupplier::DataSupplier(
126 const uno::Reference
< lang::XMultiServiceFactory
>& rxSMgr
,
127 const rtl::Reference
< Content
>& rContent
,
128 sal_Int32 nOpenMode
)
129 : m_pImpl( new DataSupplier_Impl( rxSMgr
, rContent
, nOpenMode
) )
133 //=========================================================================
135 DataSupplier::~DataSupplier()
140 //=========================================================================
142 rtl::OUString
DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex
)
144 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
146 if ( nIndex
< m_pImpl
->m_aResults
.size() )
148 rtl::OUString aId
= m_pImpl
->m_aResults
[ nIndex
]->aId
;
149 if ( !aId
.isEmpty() )
156 if ( getResult( nIndex
) )
158 rtl::OUString aId
= m_pImpl
->m_xContent
->getResourceAccess().getURL();
160 const ContentProperties
& props
161 = *( m_pImpl
->m_aResults
[ nIndex
]->pData
);
163 if ( ( aId
.lastIndexOf( '/' ) + 1 ) != aId
.getLength() )
164 aId
+= rtl::OUString("/");
166 aId
+= props
.getEscapedTitle();
168 if ( props
.isTrailingSlash() )
169 aId
+= rtl::OUString("/");
171 m_pImpl
->m_aResults
[ nIndex
]->aId
= aId
;
174 return rtl::OUString();
177 //=========================================================================
179 uno::Reference
< ucb::XContentIdentifier
>
180 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex
)
182 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
184 if ( nIndex
< m_pImpl
->m_aResults
.size() )
186 uno::Reference
< ucb::XContentIdentifier
> xId
187 = m_pImpl
->m_aResults
[ nIndex
]->xId
;
195 rtl::OUString aId
= queryContentIdentifierString( nIndex
);
196 if ( !aId
.isEmpty() )
198 uno::Reference
< ucb::XContentIdentifier
> xId
199 = new ::ucbhelper::ContentIdentifier( aId
);
200 m_pImpl
->m_aResults
[ nIndex
]->xId
= xId
;
203 return uno::Reference
< ucb::XContentIdentifier
>();
206 //=========================================================================
208 uno::Reference
< ucb::XContent
>
209 DataSupplier::queryContent( sal_uInt32 nIndex
)
211 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
213 if ( nIndex
< m_pImpl
->m_aResults
.size() )
215 uno::Reference
< ucb::XContent
> xContent
216 = m_pImpl
->m_aResults
[ nIndex
]->xContent
;
224 uno::Reference
< ucb::XContentIdentifier
> xId
225 = queryContentIdentifier( nIndex
);
230 uno::Reference
< ucb::XContent
> xContent
231 = m_pImpl
->m_xContent
->getProvider()->queryContent( xId
);
232 m_pImpl
->m_aResults
[ nIndex
]->xContent
= xContent
;
236 catch ( ucb::IllegalIdentifierException
& )
240 return uno::Reference
< ucb::XContent
>();
243 //=========================================================================
245 sal_Bool
DataSupplier::getResult( sal_uInt32 nIndex
)
247 osl::ClearableGuard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
249 if ( m_pImpl
->m_aResults
.size() > nIndex
)
251 // Result already present.
258 if ( m_pImpl
->m_aResults
.size() > nIndex
)
260 // Result already present.
268 //=========================================================================
270 sal_uInt32
DataSupplier::totalCount()
275 return m_pImpl
->m_aResults
.size();
278 //=========================================================================
280 sal_uInt32
DataSupplier::currentCount()
282 return m_pImpl
->m_aResults
.size();
285 //=========================================================================
287 sal_Bool
DataSupplier::isCountFinal()
289 return m_pImpl
->m_bCountFinal
;
292 //=========================================================================
294 uno::Reference
< sdbc::XRow
> DataSupplier::queryPropertyValues(
297 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
299 if ( nIndex
< m_pImpl
->m_aResults
.size() )
301 uno::Reference
< sdbc::XRow
> xRow
= m_pImpl
->m_aResults
[ nIndex
]->xRow
;
309 if ( getResult( nIndex
) )
311 uno::Reference
< sdbc::XRow
> xRow
312 = Content::getPropertyValues(
314 getResultSet()->getProperties(),
315 *(m_pImpl
->m_aResults
[ nIndex
]->pData
),
316 rtl::Reference
< ::ucbhelper::ContentProviderImplHelper
>(
317 m_pImpl
->m_xContent
->getProvider().get() ),
318 queryContentIdentifierString( nIndex
) );
319 m_pImpl
->m_aResults
[ nIndex
]->xRow
= xRow
;
323 return uno::Reference
< sdbc::XRow
>();
326 //=========================================================================
328 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex
)
330 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
332 if ( nIndex
< m_pImpl
->m_aResults
.size() )
333 m_pImpl
->m_aResults
[ nIndex
]->xRow
= uno::Reference
< sdbc::XRow
>();
336 //=========================================================================
338 void DataSupplier::close()
342 //=========================================================================
344 void DataSupplier::validate()
345 throw( ucb::ResultSetException
)
347 if ( m_pImpl
->m_bThrowException
)
348 throw ucb::ResultSetException();
351 //=========================================================================
352 sal_Bool
DataSupplier::getData()
354 osl::ClearableGuard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
356 if ( !m_pImpl
->m_bCountFinal
)
358 std::vector
< rtl::OUString
> propertyNames
;
359 ContentProperties::UCBNamesToDAVNames(
360 getResultSet()->getProperties(), propertyNames
);
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.
366 std::vector
< rtl::OUString
>::const_iterator it
367 = propertyNames
.begin();
368 std::vector
< rtl::OUString
>::const_iterator end
369 = propertyNames
.end();
373 if ( (*it
).equals( DAVProperties::RESOURCETYPE
) )
380 propertyNames
.push_back( DAVProperties::RESOURCETYPE
);
382 std::vector
< DAVResource
> resources
;
385 // propfind depth 1, get property values for parent AND for each
387 m_pImpl
->m_xContent
->getResourceAccess()
391 getResultSet()->getEnvironment() );
393 catch ( DAVException
& )
395 // OSL_FAIL( "PROPFIND : DAVException" );
396 m_pImpl
->m_bThrowException
= sal_True
;
399 if ( !m_pImpl
->m_bThrowException
)
404 m_pImpl
->m_xContent
->getResourceAccess().getURL() );
405 rtl::OUString aPath
= aURI
.GetPath();
407 if ( aPath
.getStr()[ aPath
.getLength() - 1 ]
408 == sal_Unicode( '/' ) )
409 aPath
= aPath
.copy( 0, aPath
.getLength() - 1 );
411 aPath
= NeonUri::unescape( aPath
);
412 bool bFoundParent
= false;
414 for ( sal_uInt32 n
= 0; n
< resources
.size(); ++n
)
416 const DAVResource
& rRes
= resources
[ n
];
418 // Filter parent, which is contained somewhere(!) in
424 NeonUri
aCurrURI( rRes
.uri
);
425 rtl::OUString aCurrPath
= aCurrURI
.GetPath();
426 if ( aCurrPath
.getStr()[
427 aCurrPath
.getLength() - 1 ]
428 == sal_Unicode( '/' ) )
432 aCurrPath
.getLength() - 1 );
434 aCurrPath
= NeonUri::unescape( aCurrPath
);
435 if ( aPath
== aCurrPath
)
441 catch ( DAVException
const & )
443 // do nothing, ignore error. continue.
447 ContentProperties
* pContentProperties
448 = new ContentProperties( rRes
);
450 // Check resource against open mode.
451 switch ( m_pImpl
->m_nOpenMode
)
453 case ucb::OpenMode::FOLDERS
:
455 sal_Bool bFolder
= sal_False
;
457 const uno::Any
& rValue
458 = pContentProperties
->getValue(
459 rtl::OUString( "IsFolder" ) );
468 case ucb::OpenMode::DOCUMENTS
:
470 sal_Bool bDocument
= sal_False
;
472 const uno::Any
& rValue
473 = pContentProperties
->getValue(
474 rtl::OUString( "IsDocument" ) );
475 rValue
>>= bDocument
;
483 case ucb::OpenMode::ALL
:
488 m_pImpl
->m_aResults
.push_back(
489 new ResultListEntry( pContentProperties
) );
492 catch ( DAVException
const & )
497 m_pImpl
->m_bCountFinal
= sal_True
;
499 // Callback possible, because listeners may be informed!
501 getResultSet()->rowCountFinal();
503 return !m_pImpl
->m_bThrowException
;
506 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */