Update ooo320-m1
[ooovba.git] / ucb / source / ucp / tdoc / tdoc_datasupplier.cxx
blob4ea50aba52660e53256ca48a6b15bf0b05137884
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tdoc_datasupplier.cxx,v $
10 * $Revision: 1.7 $
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 /**************************************************************************
35 TODO
36 **************************************************************************
38 *************************************************************************/
40 #include <vector>
42 #include "osl/diagnose.h"
43 #include "ucbhelper/contentidentifier.hxx"
45 #include "tdoc_datasupplier.hxx"
46 #include "tdoc_content.hxx"
48 using namespace com::sun::star;
49 using namespace tdoc_ucp;
51 namespace tdoc_ucp
54 //=========================================================================
56 // struct ResultListEntry.
58 //=========================================================================
60 struct ResultListEntry
62 rtl::OUString aURL;
63 uno::Reference< ucb::XContentIdentifier > xId;
64 uno::Reference< ucb::XContent > xContent;
65 uno::Reference< sdbc::XRow > xRow;
67 ResultListEntry( const rtl::OUString& rURL ) : aURL( rURL ) {}
70 //=========================================================================
72 // ResultList.
74 //=========================================================================
76 typedef std::vector< ResultListEntry* > ResultList;
78 //=========================================================================
80 // struct DataSupplier_Impl.
82 //=========================================================================
84 struct DataSupplier_Impl
86 osl::Mutex m_aMutex;
87 ResultList m_aResults;
88 rtl::Reference< Content > m_xContent;
89 uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
90 uno::Sequence< rtl::OUString > * m_pNamesOfChildren;
91 sal_Int32 m_nOpenMode;
92 bool m_bCountFinal;
93 bool m_bThrowException;
95 DataSupplier_Impl(
96 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
97 const rtl::Reference< Content >& rContent,
98 sal_Int32 nOpenMode )
99 : m_xContent( rContent ), m_xSMgr( rxSMgr ),
100 m_pNamesOfChildren( 0 ), m_nOpenMode( nOpenMode ),
101 m_bCountFinal( false ), m_bThrowException( false )
103 ~DataSupplier_Impl();
106 //=========================================================================
107 DataSupplier_Impl::~DataSupplier_Impl()
109 ResultList::const_iterator it = m_aResults.begin();
110 ResultList::const_iterator end = m_aResults.end();
112 while ( it != end )
114 delete (*it);
115 it++;
118 delete m_pNamesOfChildren;
123 //=========================================================================
124 //=========================================================================
126 // DataSupplier Implementation.
128 //=========================================================================
129 //=========================================================================
131 ResultSetDataSupplier::ResultSetDataSupplier(
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 //=========================================================================
140 // virtual
141 ResultSetDataSupplier::~ResultSetDataSupplier()
143 delete m_pImpl;
146 //=========================================================================
147 // virtual
148 rtl::OUString
149 ResultSetDataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
151 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
153 if ( nIndex < m_pImpl->m_aResults.size() )
155 rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aURL;
156 if ( aId.getLength() )
158 // Already cached.
159 return aId;
163 if ( getResult( nIndex ) )
165 // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
166 return m_pImpl->m_aResults[ nIndex ]->aURL;
168 return rtl::OUString();
171 //=========================================================================
172 // virtual
173 uno::Reference< ucb::XContentIdentifier >
174 ResultSetDataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
176 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
178 if ( nIndex < m_pImpl->m_aResults.size() )
180 uno::Reference< ucb::XContentIdentifier > xId
181 = m_pImpl->m_aResults[ nIndex ]->xId;
182 if ( xId.is() )
184 // Already cached.
185 return xId;
189 rtl::OUString aId = queryContentIdentifierString( nIndex );
190 if ( aId.getLength() )
192 uno::Reference< ucb::XContentIdentifier > xId
193 = new ::ucbhelper::ContentIdentifier( aId );
194 m_pImpl->m_aResults[ nIndex ]->xId = xId;
195 return xId;
197 return uno::Reference< ucb::XContentIdentifier >();
200 //=========================================================================
201 // virtual
202 uno::Reference< ucb::XContent >
203 ResultSetDataSupplier::queryContent( sal_uInt32 nIndex )
205 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
207 if ( nIndex < m_pImpl->m_aResults.size() )
209 uno::Reference< ucb::XContent > xContent
210 = m_pImpl->m_aResults[ nIndex ]->xContent;
211 if ( xContent.is() )
213 // Already cached.
214 return xContent;
218 uno::Reference< ucb::XContentIdentifier > xId
219 = queryContentIdentifier( nIndex );
220 if ( xId.is() )
224 uno::Reference< ucb::XContent > xContent
225 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
226 m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
227 return xContent;
230 catch ( ucb::IllegalIdentifierException const & )
234 return uno::Reference< ucb::XContent >();
237 //=========================================================================
238 // virtual
239 sal_Bool ResultSetDataSupplier::getResult( sal_uInt32 nIndex )
241 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
243 if ( m_pImpl->m_aResults.size() > nIndex )
245 // Result already present.
246 return sal_True;
249 // Result not (yet) present.
251 if ( m_pImpl->m_bCountFinal )
252 return sal_False;
254 // Try to obtain result...
256 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
257 bool bFound = false;
259 if ( queryNamesOfChildren() )
261 for ( sal_uInt32 n = nOldCount;
262 n < sal::static_int_cast<sal_uInt32>(
263 m_pImpl->m_pNamesOfChildren->getLength());
264 ++n )
266 const rtl::OUString & rName
267 = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
269 if ( !rName.getLength() )
271 OSL_ENSURE( sal_False,
272 "ResultDataSupplier::getResult - Empty name!" );
273 break;
276 // Assemble URL for child.
277 rtl::OUString aURL = assembleChildURL( rName );
279 m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
281 if ( n == nIndex )
283 // Result obtained.
284 bFound = true;
285 break;
290 if ( !bFound )
291 m_pImpl->m_bCountFinal = sal_True;
293 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
294 if ( xResultSet.is() )
296 // Callbacks follow!
297 aGuard.clear();
299 if ( nOldCount < m_pImpl->m_aResults.size() )
300 xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
302 if ( m_pImpl->m_bCountFinal )
303 xResultSet->rowCountFinal();
306 return bFound;
309 //=========================================================================
310 // virtual
311 sal_uInt32 ResultSetDataSupplier::totalCount()
313 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
315 if ( m_pImpl->m_bCountFinal )
316 return m_pImpl->m_aResults.size();
318 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
320 if ( queryNamesOfChildren() )
322 for ( sal_uInt32 n = nOldCount;
323 n < sal::static_int_cast<sal_uInt32>(
324 m_pImpl->m_pNamesOfChildren->getLength());
325 ++n )
327 const rtl::OUString & rName
328 = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
330 if ( !rName.getLength() )
332 OSL_ENSURE( sal_False,
333 "ResultDataSupplier::getResult - Empty name!" );
334 break;
337 // Assemble URL for child.
338 rtl::OUString aURL = assembleChildURL( rName );
340 m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
344 m_pImpl->m_bCountFinal = sal_True;
346 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
347 if ( xResultSet.is() )
349 // Callbacks follow!
350 aGuard.clear();
352 if ( nOldCount < m_pImpl->m_aResults.size() )
353 xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
355 xResultSet->rowCountFinal();
358 return m_pImpl->m_aResults.size();
361 //=========================================================================
362 // virtual
363 sal_uInt32 ResultSetDataSupplier::currentCount()
365 return m_pImpl->m_aResults.size();
368 //=========================================================================
369 // virtual
370 sal_Bool ResultSetDataSupplier::isCountFinal()
372 return m_pImpl->m_bCountFinal;
375 //=========================================================================
376 // virtual
377 uno::Reference< sdbc::XRow >
378 ResultSetDataSupplier::queryPropertyValues( sal_uInt32 nIndex )
380 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
382 if ( nIndex < m_pImpl->m_aResults.size() )
384 uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
385 if ( xRow.is() )
387 // Already cached.
388 return xRow;
392 if ( getResult( nIndex ) )
394 uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
395 m_pImpl->m_xSMgr,
396 getResultSet()->getProperties(),
397 m_pImpl->m_xContent->getContentProvider().get(),
398 queryContentIdentifierString( nIndex ) );
399 m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
400 return xRow;
403 return uno::Reference< sdbc::XRow >();
406 //=========================================================================
407 // virtual
408 void ResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
410 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
412 if ( nIndex < m_pImpl->m_aResults.size() )
413 m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
416 //=========================================================================
417 // virtual
418 void ResultSetDataSupplier::close()
422 //=========================================================================
423 // virtual
424 void ResultSetDataSupplier::validate()
425 throw( ucb::ResultSetException )
427 if ( m_pImpl->m_bThrowException )
428 throw ucb::ResultSetException();
431 //=========================================================================
432 bool ResultSetDataSupplier::queryNamesOfChildren()
434 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
436 if ( m_pImpl->m_pNamesOfChildren == 0 )
438 uno::Sequence< rtl::OUString > * pNamesOfChildren
439 = new uno::Sequence< rtl::OUString >();
441 if ( !m_pImpl->m_xContent->getContentProvider()->queryNamesOfChildren(
442 m_pImpl->m_xContent->getIdentifier()->getContentIdentifier(),
443 *pNamesOfChildren ) )
445 OSL_ENSURE( false, "Got no list of children!" );
446 m_pImpl->m_bThrowException = sal_True;
447 return false;
449 else
451 m_pImpl->m_pNamesOfChildren = pNamesOfChildren;
454 return true;
457 //=========================================================================
458 ::rtl::OUString
459 ResultSetDataSupplier::assembleChildURL( const ::rtl::OUString& aName )
461 rtl::OUString aContURL
462 = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
463 rtl::OUString aURL( aContURL );
465 sal_Int32 nUrlEnd = aURL.lastIndexOf( '/' );
466 if ( nUrlEnd != aURL.getLength() - 1 )
467 aURL += rtl::OUString::createFromAscii( "/" );
469 aURL += aName;
470 return aURL;