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: pkgdatasupplier.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 *************************************************************************/
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
;
58 //=========================================================================
60 // struct ResultListEntry.
62 //=========================================================================
64 struct ResultListEntry
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 //=========================================================================
78 //=========================================================================
80 typedef std::vector
< ResultListEntry
* > ResultList
;
82 //=========================================================================
84 // struct DataSupplier_Impl.
86 //=========================================================================
88 struct DataSupplier_Impl
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
;
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();
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 //=========================================================================
143 DataSupplier::~DataSupplier()
148 //=========================================================================
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() )
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 //=========================================================================
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
;
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
;
198 return uno::Reference
< ucb::XContentIdentifier
>();
201 //=========================================================================
203 uno::Reference
< ucb::XContent
> DataSupplier::queryContent(
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
;
219 uno::Reference
< ucb::XContentIdentifier
> xId
220 = queryContentIdentifier( nIndex
);
225 uno::Reference
< ucb::XContent
> xContent
226 = m_pImpl
->m_xContent
->getProvider()->queryContent( xId
);
227 m_pImpl
->m_aResults
[ nIndex
]->xContent
= xContent
;
231 catch ( ucb::IllegalIdentifierException
const & )
235 return uno::Reference
< ucb::XContent
>();
238 //=========================================================================
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.
250 // Result not (yet) present.
252 if ( m_pImpl
->m_bCountFinal
)
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
;
270 OSL_ENSURE( sal_False
,
271 "DataSupplier::getResult - Got no XNamed!" );
275 rtl::OUString aName
= xNamed
->getName();
277 if ( !aName
.getLength() )
279 OSL_ENSURE( sal_False
,
280 "DataSupplier::getResult - Empty name!" );
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
)
298 catch ( container::NoSuchElementException
const & )
300 m_pImpl
->m_bThrowException
= sal_True
;
303 catch ( lang::WrappedTargetException
const & )
305 m_pImpl
->m_bThrowException
= sal_True
;
311 m_pImpl
->m_bCountFinal
= sal_True
;
313 rtl::Reference
< ::ucbhelper::ResultSet
> xResultSet
= getResultSet().get();
314 if ( xResultSet
.is() )
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();
330 //=========================================================================
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
;
350 OSL_ENSURE( sal_False
,
351 "DataSupplier::getResult - Got no XNamed!" );
355 rtl::OUString aName
= xNamed
->getName();
357 if ( !aName
.getLength() )
359 OSL_ENSURE( sal_False
,
360 "DataSupplier::getResult - Empty name!" );
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
;
374 catch ( lang::WrappedTargetException
const & )
376 m_pImpl
->m_bThrowException
= sal_True
;
381 m_pImpl
->m_bCountFinal
= sal_True
;
383 rtl::Reference
< ::ucbhelper::ResultSet
> xResultSet
= getResultSet().get();
384 if ( xResultSet
.is() )
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 //=========================================================================
401 sal_uInt32
DataSupplier::currentCount()
403 return m_pImpl
->m_aResults
.size();
406 //=========================================================================
408 sal_Bool
DataSupplier::isCountFinal()
410 return m_pImpl
->m_bCountFinal
;
413 //=========================================================================
415 uno::Reference
< sdbc::XRow
> DataSupplier::queryPropertyValues(
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
;
430 if ( getResult( nIndex
) )
432 uno::Reference
< sdbc::XRow
> xRow
= Content::getPropertyValues(
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
;
442 return uno::Reference
< sdbc::XRow
>();
445 //=========================================================================
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 //=========================================================================
457 void DataSupplier::close()
461 //=========================================================================
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
)
474 rtl::OUString aContURL
475 = m_pImpl
->m_xContent
->getIdentifier()->getContentIdentifier();
476 sal_Int32 nParam
= aContURL
.indexOf( '?' );
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
);
492 sal_Int32 nPackageUrlEnd
= aURL
.lastIndexOf( '/' );
493 if ( nPackageUrlEnd
!= aURL
.getLength() - 1 )
494 aURL
+= rtl::OUString::createFromAscii( "/" );
496 aURL
+= ::ucb_impl::urihelper::encodeSegment( aName
);