Bump for 3.6-28
[LibreOffice.git] / ucb / source / ucp / tdoc / tdoc_datasupplier.cxx
blob1bfc40a1f55b9f934f2c8dd9fd462deb0d5fa781
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 /**************************************************************************
31 TODO
32 **************************************************************************
34 *************************************************************************/
36 #include <vector>
38 #include "osl/diagnose.h"
39 #include "ucbhelper/contentidentifier.hxx"
41 #include "tdoc_datasupplier.hxx"
42 #include "tdoc_content.hxx"
44 using namespace com::sun::star;
45 using namespace tdoc_ucp;
47 namespace tdoc_ucp
50 //=========================================================================
52 // struct ResultListEntry.
54 //=========================================================================
56 struct ResultListEntry
58 rtl::OUString aURL;
59 uno::Reference< ucb::XContentIdentifier > xId;
60 uno::Reference< ucb::XContent > xContent;
61 uno::Reference< sdbc::XRow > xRow;
63 ResultListEntry( const rtl::OUString& rURL ) : aURL( rURL ) {}
66 //=========================================================================
68 // ResultList.
70 //=========================================================================
72 typedef std::vector< ResultListEntry* > ResultList;
74 //=========================================================================
76 // struct DataSupplier_Impl.
78 //=========================================================================
80 struct DataSupplier_Impl
82 osl::Mutex m_aMutex;
83 ResultList m_aResults;
84 rtl::Reference< Content > m_xContent;
85 uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
86 uno::Sequence< rtl::OUString > * m_pNamesOfChildren;
87 sal_Int32 m_nOpenMode;
88 bool m_bCountFinal;
89 bool m_bThrowException;
91 DataSupplier_Impl(
92 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
93 const rtl::Reference< Content >& rContent,
94 sal_Int32 nOpenMode )
95 : m_xContent( rContent ), m_xSMgr( rxSMgr ),
96 m_pNamesOfChildren( 0 ), m_nOpenMode( nOpenMode ),
97 m_bCountFinal( false ), m_bThrowException( false )
99 ~DataSupplier_Impl();
102 //=========================================================================
103 DataSupplier_Impl::~DataSupplier_Impl()
105 ResultList::const_iterator it = m_aResults.begin();
106 ResultList::const_iterator end = m_aResults.end();
108 while ( it != end )
110 delete (*it);
111 ++it;
114 delete m_pNamesOfChildren;
119 //=========================================================================
120 //=========================================================================
122 // DataSupplier Implementation.
124 //=========================================================================
125 //=========================================================================
127 ResultSetDataSupplier::ResultSetDataSupplier(
128 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
129 const rtl::Reference< Content >& rContent,
130 sal_Int32 nOpenMode )
131 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
135 //=========================================================================
136 // virtual
137 ResultSetDataSupplier::~ResultSetDataSupplier()
139 delete m_pImpl;
142 //=========================================================================
143 // virtual
144 rtl::OUString
145 ResultSetDataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
147 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
149 if ( nIndex < m_pImpl->m_aResults.size() )
151 rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aURL;
152 if ( !aId.isEmpty() )
154 // Already cached.
155 return aId;
159 if ( getResult( nIndex ) )
161 // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
162 return m_pImpl->m_aResults[ nIndex ]->aURL;
164 return rtl::OUString();
167 //=========================================================================
168 // virtual
169 uno::Reference< ucb::XContentIdentifier >
170 ResultSetDataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
172 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
174 if ( nIndex < m_pImpl->m_aResults.size() )
176 uno::Reference< ucb::XContentIdentifier > xId
177 = m_pImpl->m_aResults[ nIndex ]->xId;
178 if ( xId.is() )
180 // Already cached.
181 return xId;
185 rtl::OUString aId = queryContentIdentifierString( nIndex );
186 if ( !aId.isEmpty() )
188 uno::Reference< ucb::XContentIdentifier > xId
189 = new ::ucbhelper::ContentIdentifier( aId );
190 m_pImpl->m_aResults[ nIndex ]->xId = xId;
191 return xId;
193 return uno::Reference< ucb::XContentIdentifier >();
196 //=========================================================================
197 // virtual
198 uno::Reference< ucb::XContent >
199 ResultSetDataSupplier::queryContent( sal_uInt32 nIndex )
201 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
203 if ( nIndex < m_pImpl->m_aResults.size() )
205 uno::Reference< ucb::XContent > xContent
206 = m_pImpl->m_aResults[ nIndex ]->xContent;
207 if ( xContent.is() )
209 // Already cached.
210 return xContent;
214 uno::Reference< ucb::XContentIdentifier > xId
215 = queryContentIdentifier( nIndex );
216 if ( xId.is() )
220 uno::Reference< ucb::XContent > xContent
221 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
222 m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
223 return xContent;
226 catch ( ucb::IllegalIdentifierException const & )
230 return uno::Reference< ucb::XContent >();
233 //=========================================================================
234 // virtual
235 sal_Bool ResultSetDataSupplier::getResult( sal_uInt32 nIndex )
237 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
239 if ( m_pImpl->m_aResults.size() > nIndex )
241 // Result already present.
242 return sal_True;
245 // Result not (yet) present.
247 if ( m_pImpl->m_bCountFinal )
248 return sal_False;
250 // Try to obtain result...
252 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
253 bool bFound = false;
255 if ( queryNamesOfChildren() )
257 for ( sal_uInt32 n = nOldCount;
258 n < sal::static_int_cast<sal_uInt32>(
259 m_pImpl->m_pNamesOfChildren->getLength());
260 ++n )
262 const rtl::OUString & rName
263 = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
265 if ( rName.isEmpty() )
267 OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
268 break;
271 // Assemble URL for child.
272 rtl::OUString aURL = assembleChildURL( rName );
274 m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
276 if ( n == nIndex )
278 // Result obtained.
279 bFound = true;
280 break;
285 if ( !bFound )
286 m_pImpl->m_bCountFinal = sal_True;
288 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
289 if ( xResultSet.is() )
291 // Callbacks follow!
292 aGuard.clear();
294 if ( nOldCount < m_pImpl->m_aResults.size() )
295 xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
297 if ( m_pImpl->m_bCountFinal )
298 xResultSet->rowCountFinal();
301 return bFound;
304 //=========================================================================
305 // virtual
306 sal_uInt32 ResultSetDataSupplier::totalCount()
308 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
310 if ( m_pImpl->m_bCountFinal )
311 return m_pImpl->m_aResults.size();
313 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
315 if ( queryNamesOfChildren() )
317 for ( sal_uInt32 n = nOldCount;
318 n < sal::static_int_cast<sal_uInt32>(
319 m_pImpl->m_pNamesOfChildren->getLength());
320 ++n )
322 const rtl::OUString & rName
323 = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
325 if ( rName.isEmpty() )
327 OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
328 break;
331 // Assemble URL for child.
332 rtl::OUString aURL = assembleChildURL( rName );
334 m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
338 m_pImpl->m_bCountFinal = sal_True;
340 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
341 if ( xResultSet.is() )
343 // Callbacks follow!
344 aGuard.clear();
346 if ( nOldCount < m_pImpl->m_aResults.size() )
347 xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
349 xResultSet->rowCountFinal();
352 return m_pImpl->m_aResults.size();
355 //=========================================================================
356 // virtual
357 sal_uInt32 ResultSetDataSupplier::currentCount()
359 return m_pImpl->m_aResults.size();
362 //=========================================================================
363 // virtual
364 sal_Bool ResultSetDataSupplier::isCountFinal()
366 return m_pImpl->m_bCountFinal;
369 //=========================================================================
370 // virtual
371 uno::Reference< sdbc::XRow >
372 ResultSetDataSupplier::queryPropertyValues( sal_uInt32 nIndex )
374 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
376 if ( nIndex < m_pImpl->m_aResults.size() )
378 uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
379 if ( xRow.is() )
381 // Already cached.
382 return xRow;
386 if ( getResult( nIndex ) )
388 uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
389 m_pImpl->m_xSMgr,
390 getResultSet()->getProperties(),
391 m_pImpl->m_xContent->getContentProvider().get(),
392 queryContentIdentifierString( nIndex ) );
393 m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
394 return xRow;
397 return uno::Reference< sdbc::XRow >();
400 //=========================================================================
401 // virtual
402 void ResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
404 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
406 if ( nIndex < m_pImpl->m_aResults.size() )
407 m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
410 //=========================================================================
411 // virtual
412 void ResultSetDataSupplier::close()
416 //=========================================================================
417 // virtual
418 void ResultSetDataSupplier::validate()
419 throw( ucb::ResultSetException )
421 if ( m_pImpl->m_bThrowException )
422 throw ucb::ResultSetException();
425 //=========================================================================
426 bool ResultSetDataSupplier::queryNamesOfChildren()
428 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
430 if ( m_pImpl->m_pNamesOfChildren == 0 )
432 uno::Sequence< rtl::OUString > * pNamesOfChildren
433 = new uno::Sequence< rtl::OUString >();
435 if ( !m_pImpl->m_xContent->getContentProvider()->queryNamesOfChildren(
436 m_pImpl->m_xContent->getIdentifier()->getContentIdentifier(),
437 *pNamesOfChildren ) )
439 OSL_FAIL( "Got no list of children!" );
440 m_pImpl->m_bThrowException = sal_True;
441 return false;
443 else
445 m_pImpl->m_pNamesOfChildren = pNamesOfChildren;
448 return true;
451 //=========================================================================
452 ::rtl::OUString
453 ResultSetDataSupplier::assembleChildURL( const ::rtl::OUString& aName )
455 rtl::OUString aContURL
456 = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
457 rtl::OUString aURL( aContURL );
459 sal_Int32 nUrlEnd = aURL.lastIndexOf( '/' );
460 if ( nUrlEnd != aURL.getLength() - 1 )
461 aURL += rtl::OUString("/");
463 aURL += aName;
464 return aURL;
467 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */