Update ooo320-m1
[ooovba.git] / ucb / source / ucp / package / pkgdatasupplier.cxx
blobc465e8d7b42af3eab35867723a77795b8795a8f8
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: pkgdatasupplier.cxx,v $
10 * $Revision: 1.16 $
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>
41 #include <osl/diagnose.h>
42 #include <com/sun/star/container/XEnumeration.hpp>
43 #include <com/sun/star/container/XNamed.hpp>
44 #include <ucbhelper/contentidentifier.hxx>
45 #include <ucbhelper/providerhelper.hxx>
46 #include "pkgdatasupplier.hxx"
47 #include "pkgcontent.hxx"
48 #include "pkgprovider.hxx"
50 #include "../inc/urihelper.hxx"
52 using namespace com::sun::star;
53 using namespace package_ucp;
55 namespace package_ucp
58 //=========================================================================
60 // struct ResultListEntry.
62 //=========================================================================
64 struct ResultListEntry
66 rtl::OUString aURL;
67 uno::Reference< ucb::XContentIdentifier > xId;
68 uno::Reference< ucb::XContent > xContent;
69 uno::Reference< sdbc::XRow > xRow;
71 ResultListEntry( const rtl::OUString& rURL ) : aURL( rURL ) {}
74 //=========================================================================
76 // ResultList.
78 //=========================================================================
80 typedef std::vector< ResultListEntry* > ResultList;
82 //=========================================================================
84 // struct DataSupplier_Impl.
86 //=========================================================================
88 struct DataSupplier_Impl
90 osl::Mutex m_aMutex;
91 ResultList m_aResults;
92 rtl::Reference< Content > m_xContent;
93 uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
94 uno::Reference< container::XEnumeration > m_xFolderEnum;
95 sal_Int32 m_nOpenMode;
96 sal_Bool m_bCountFinal;
97 sal_Bool m_bThrowException;
99 DataSupplier_Impl(
100 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
101 const rtl::Reference< Content >& rContent,
102 sal_Int32 nOpenMode )
103 : m_xContent( rContent ), m_xSMgr( rxSMgr ),
104 m_xFolderEnum( rContent->getIterator() ), m_nOpenMode( nOpenMode ),
105 m_bCountFinal( !m_xFolderEnum.is() ), m_bThrowException( m_bCountFinal )
107 ~DataSupplier_Impl();
110 //=========================================================================
111 DataSupplier_Impl::~DataSupplier_Impl()
113 ResultList::const_iterator it = m_aResults.begin();
114 ResultList::const_iterator end = m_aResults.end();
116 while ( it != end )
118 delete (*it);
119 it++;
125 //=========================================================================
126 //=========================================================================
128 // DataSupplier Implementation.
130 //=========================================================================
131 //=========================================================================
133 DataSupplier::DataSupplier(
134 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
135 const rtl::Reference< Content >& rContent,
136 sal_Int32 nOpenMode )
137 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
141 //=========================================================================
142 // virtual
143 DataSupplier::~DataSupplier()
145 delete m_pImpl;
148 //=========================================================================
149 // virtual
150 rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
152 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
154 if ( nIndex < m_pImpl->m_aResults.size() )
156 rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aURL;
157 if ( aId.getLength() )
159 // Already cached.
160 return aId;
164 if ( getResult( nIndex ) )
166 // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
167 return m_pImpl->m_aResults[ nIndex ]->aURL;
169 return rtl::OUString();
172 //=========================================================================
173 // virtual
174 uno::Reference< ucb::XContentIdentifier >
175 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
177 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
179 if ( nIndex < m_pImpl->m_aResults.size() )
181 uno::Reference< ucb::XContentIdentifier > xId
182 = m_pImpl->m_aResults[ nIndex ]->xId;
183 if ( xId.is() )
185 // Already cached.
186 return xId;
190 rtl::OUString aId = queryContentIdentifierString( nIndex );
191 if ( aId.getLength() )
193 uno::Reference< ucb::XContentIdentifier > xId
194 = new ::ucbhelper::ContentIdentifier( aId );
195 m_pImpl->m_aResults[ nIndex ]->xId = xId;
196 return xId;
198 return uno::Reference< ucb::XContentIdentifier >();
201 //=========================================================================
202 // virtual
203 uno::Reference< ucb::XContent > DataSupplier::queryContent(
204 sal_uInt32 nIndex )
206 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
208 if ( nIndex < m_pImpl->m_aResults.size() )
210 uno::Reference< ucb::XContent > xContent
211 = m_pImpl->m_aResults[ nIndex ]->xContent;
212 if ( xContent.is() )
214 // Already cached.
215 return xContent;
219 uno::Reference< ucb::XContentIdentifier > xId
220 = queryContentIdentifier( nIndex );
221 if ( xId.is() )
225 uno::Reference< ucb::XContent > xContent
226 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
227 m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
228 return xContent;
231 catch ( ucb::IllegalIdentifierException const & )
235 return uno::Reference< ucb::XContent >();
238 //=========================================================================
239 // virtual
240 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
242 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
244 if ( m_pImpl->m_aResults.size() > nIndex )
246 // Result already present.
247 return sal_True;
250 // Result not (yet) present.
252 if ( m_pImpl->m_bCountFinal )
253 return sal_False;
255 // Try to obtain result...
257 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
258 sal_Bool bFound = sal_False;
259 sal_uInt32 nPos = nOldCount;
261 while ( m_pImpl->m_xFolderEnum->hasMoreElements() )
265 uno::Reference< container::XNamed > xNamed;
266 m_pImpl->m_xFolderEnum->nextElement() >>= xNamed;
268 if ( !xNamed.is() )
270 OSL_ENSURE( sal_False,
271 "DataSupplier::getResult - Got no XNamed!" );
272 break;
275 rtl::OUString aName = xNamed->getName();
277 if ( !aName.getLength() )
279 OSL_ENSURE( sal_False,
280 "DataSupplier::getResult - Empty name!" );
281 break;
284 // Assemble URL for child.
285 rtl::OUString aURL = assembleChildURL( aName );
287 m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
289 if ( nPos == nIndex )
291 // Result obtained.
292 bFound = sal_True;
293 break;
296 nPos++;
298 catch ( container::NoSuchElementException const & )
300 m_pImpl->m_bThrowException = sal_True;
301 break;
303 catch ( lang::WrappedTargetException const & )
305 m_pImpl->m_bThrowException = sal_True;
306 break;
310 if ( !bFound )
311 m_pImpl->m_bCountFinal = sal_True;
313 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
314 if ( xResultSet.is() )
316 // Callbacks follow!
317 aGuard.clear();
319 if ( nOldCount < m_pImpl->m_aResults.size() )
320 xResultSet->rowCountChanged(
321 nOldCount, m_pImpl->m_aResults.size() );
323 if ( m_pImpl->m_bCountFinal )
324 xResultSet->rowCountFinal();
327 return bFound;
330 //=========================================================================
331 // virtual
332 sal_uInt32 DataSupplier::totalCount()
334 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
336 if ( m_pImpl->m_bCountFinal )
337 return m_pImpl->m_aResults.size();
339 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
341 while ( m_pImpl->m_xFolderEnum->hasMoreElements() )
345 uno::Reference< container::XNamed > xNamed;
346 m_pImpl->m_xFolderEnum->nextElement() >>= xNamed;
348 if ( !xNamed.is() )
350 OSL_ENSURE( sal_False,
351 "DataSupplier::getResult - Got no XNamed!" );
352 break;
355 rtl::OUString aName = xNamed->getName();
357 if ( !aName.getLength() )
359 OSL_ENSURE( sal_False,
360 "DataSupplier::getResult - Empty name!" );
361 break;
364 // Assemble URL for child.
365 rtl::OUString aURL = assembleChildURL( aName );
367 m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
369 catch ( container::NoSuchElementException const & )
371 m_pImpl->m_bThrowException = sal_True;
372 break;
374 catch ( lang::WrappedTargetException const & )
376 m_pImpl->m_bThrowException = sal_True;
377 break;
381 m_pImpl->m_bCountFinal = sal_True;
383 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
384 if ( xResultSet.is() )
386 // Callbacks follow!
387 aGuard.clear();
389 if ( nOldCount < m_pImpl->m_aResults.size() )
390 xResultSet->rowCountChanged(
391 nOldCount, m_pImpl->m_aResults.size() );
393 xResultSet->rowCountFinal();
396 return m_pImpl->m_aResults.size();
399 //=========================================================================
400 // virtual
401 sal_uInt32 DataSupplier::currentCount()
403 return m_pImpl->m_aResults.size();
406 //=========================================================================
407 // virtual
408 sal_Bool DataSupplier::isCountFinal()
410 return m_pImpl->m_bCountFinal;
413 //=========================================================================
414 // virtual
415 uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues(
416 sal_uInt32 nIndex )
418 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
420 if ( nIndex < m_pImpl->m_aResults.size() )
422 uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
423 if ( xRow.is() )
425 // Already cached.
426 return xRow;
430 if ( getResult( nIndex ) )
432 uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
433 m_pImpl->m_xSMgr,
434 getResultSet()->getProperties(),
435 static_cast< ContentProvider * >(
436 m_pImpl->m_xContent->getProvider().get() ),
437 queryContentIdentifierString( nIndex ) );
438 m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
439 return xRow;
442 return uno::Reference< sdbc::XRow >();
445 //=========================================================================
446 // virtual
447 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
449 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
451 if ( nIndex < m_pImpl->m_aResults.size() )
452 m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
455 //=========================================================================
456 // virtual
457 void DataSupplier::close()
461 //=========================================================================
462 // virtual
463 void DataSupplier::validate()
464 throw( ucb::ResultSetException )
466 if ( m_pImpl->m_bThrowException )
467 throw ucb::ResultSetException();
470 //=========================================================================
471 ::rtl::OUString DataSupplier::assembleChildURL( const ::rtl::OUString& aName )
473 rtl::OUString aURL;
474 rtl::OUString aContURL
475 = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
476 sal_Int32 nParam = aContURL.indexOf( '?' );
477 if ( nParam >= 0 )
479 aURL = aContURL.copy( 0, nParam );
481 sal_Int32 nPackageUrlEnd = aURL.lastIndexOf( '/' );
482 if ( nPackageUrlEnd != aURL.getLength() - 1 )
483 aURL += rtl::OUString::createFromAscii( "/" );
485 aURL += ::ucb_impl::urihelper::encodeSegment( aName );
486 aURL += aContURL.copy( nParam );
488 else
490 aURL = aContURL;
492 sal_Int32 nPackageUrlEnd = aURL.lastIndexOf( '/' );
493 if ( nPackageUrlEnd != aURL.getLength() - 1 )
494 aURL += rtl::OUString::createFromAscii( "/" );
496 aURL += ::ucb_impl::urihelper::encodeSegment( aName );
498 return aURL;