1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 /**************************************************************************
23 **************************************************************************
25 *************************************************************************/
28 #include <osl/diagnose.h>
29 #include <com/sun/star/container/XEnumeration.hpp>
30 #include <com/sun/star/container/XNamed.hpp>
31 #include <ucbhelper/contentidentifier.hxx>
32 #include <ucbhelper/providerhelper.hxx>
33 #include "pkgdatasupplier.hxx"
34 #include "pkgcontent.hxx"
35 #include "pkgprovider.hxx"
37 #include "../inc/urihelper.hxx"
39 using namespace com::sun::star
;
40 using namespace package_ucp
;
47 // struct ResultListEntry.
51 struct ResultListEntry
54 uno::Reference
< ucb::XContentIdentifier
> xId
;
55 uno::Reference
< ucb::XContent
> xContent
;
56 uno::Reference
< sdbc::XRow
> xRow
;
58 ResultListEntry( const OUString
& rURL
) : aURL( rURL
) {}
67 typedef std::vector
< ResultListEntry
* > ResultList
;
71 // struct DataSupplier_Impl.
75 struct DataSupplier_Impl
78 ResultList m_aResults
;
79 rtl::Reference
< Content
> m_xContent
;
80 uno::Reference
< uno::XComponentContext
> m_xContext
;
81 uno::Reference
< container::XEnumeration
> m_xFolderEnum
;
82 sal_Int32 m_nOpenMode
;
84 bool m_bThrowException
;
87 const uno::Reference
< uno::XComponentContext
>& rxContext
,
88 const rtl::Reference
< Content
>& rContent
,
90 : m_xContent( rContent
), m_xContext( rxContext
),
91 m_xFolderEnum( rContent
->getIterator() ), m_nOpenMode( nOpenMode
),
92 m_bCountFinal( !m_xFolderEnum
.is() ), m_bThrowException( m_bCountFinal
)
98 DataSupplier_Impl::~DataSupplier_Impl()
100 ResultList::const_iterator it
= m_aResults
.begin();
101 ResultList::const_iterator end
= m_aResults
.end();
115 // DataSupplier Implementation.
120 DataSupplier::DataSupplier(
121 const uno::Reference
< uno::XComponentContext
>& rxContext
,
122 const rtl::Reference
< Content
>& rContent
,
123 sal_Int32 nOpenMode
)
124 : m_pImpl( new DataSupplier_Impl( rxContext
, rContent
, nOpenMode
) )
130 DataSupplier::~DataSupplier()
137 OUString
DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex
)
139 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
141 if ( nIndex
< m_pImpl
->m_aResults
.size() )
143 OUString aId
= m_pImpl
->m_aResults
[ nIndex
]->aURL
;
144 if ( !aId
.isEmpty() )
151 if ( getResult( nIndex
) )
153 // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
154 return m_pImpl
->m_aResults
[ nIndex
]->aURL
;
161 uno::Reference
< ucb::XContentIdentifier
>
162 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex
)
164 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
166 if ( nIndex
< m_pImpl
->m_aResults
.size() )
168 uno::Reference
< ucb::XContentIdentifier
> xId
169 = m_pImpl
->m_aResults
[ nIndex
]->xId
;
177 OUString aId
= queryContentIdentifierString( nIndex
);
178 if ( !aId
.isEmpty() )
180 uno::Reference
< ucb::XContentIdentifier
> xId
181 = new ::ucbhelper::ContentIdentifier( aId
);
182 m_pImpl
->m_aResults
[ nIndex
]->xId
= xId
;
185 return uno::Reference
< ucb::XContentIdentifier
>();
190 uno::Reference
< ucb::XContent
> DataSupplier::queryContent(
193 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
195 if ( nIndex
< m_pImpl
->m_aResults
.size() )
197 uno::Reference
< ucb::XContent
> xContent
198 = m_pImpl
->m_aResults
[ nIndex
]->xContent
;
206 uno::Reference
< ucb::XContentIdentifier
> xId
207 = queryContentIdentifier( nIndex
);
212 uno::Reference
< ucb::XContent
> xContent
213 = m_pImpl
->m_xContent
->getProvider()->queryContent( xId
);
214 m_pImpl
->m_aResults
[ nIndex
]->xContent
= xContent
;
218 catch ( ucb::IllegalIdentifierException
const & )
222 return uno::Reference
< ucb::XContent
>();
227 bool DataSupplier::getResult( sal_uInt32 nIndex
)
229 osl::ClearableGuard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
231 if ( m_pImpl
->m_aResults
.size() > nIndex
)
233 // Result already present.
237 // Result not (yet) present.
239 if ( m_pImpl
->m_bCountFinal
)
242 // Try to obtain result...
244 sal_uInt32 nOldCount
= m_pImpl
->m_aResults
.size();
246 sal_uInt32 nPos
= nOldCount
;
248 while ( m_pImpl
->m_xFolderEnum
->hasMoreElements() )
252 uno::Reference
< container::XNamed
> xNamed
;
253 m_pImpl
->m_xFolderEnum
->nextElement() >>= xNamed
;
257 OSL_FAIL( "DataSupplier::getResult - Got no XNamed!" );
261 OUString aName
= xNamed
->getName();
263 if ( aName
.isEmpty() )
265 OSL_FAIL( "DataSupplier::getResult - Empty name!" );
269 // Assemble URL for child.
270 OUString aURL
= assembleChildURL( aName
);
272 m_pImpl
->m_aResults
.push_back( new ResultListEntry( aURL
) );
274 if ( nPos
== nIndex
)
283 catch ( container::NoSuchElementException
const & )
285 m_pImpl
->m_bThrowException
= true;
288 catch ( lang::WrappedTargetException
const & )
290 m_pImpl
->m_bThrowException
= true;
296 m_pImpl
->m_bCountFinal
= true;
298 rtl::Reference
< ::ucbhelper::ResultSet
> xResultSet
= getResultSet().get();
299 if ( xResultSet
.is() )
304 if ( nOldCount
< m_pImpl
->m_aResults
.size() )
305 xResultSet
->rowCountChanged(
306 nOldCount
, m_pImpl
->m_aResults
.size() );
308 if ( m_pImpl
->m_bCountFinal
)
309 xResultSet
->rowCountFinal();
317 sal_uInt32
DataSupplier::totalCount()
319 osl::ClearableGuard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
321 if ( m_pImpl
->m_bCountFinal
)
322 return m_pImpl
->m_aResults
.size();
324 sal_uInt32 nOldCount
= m_pImpl
->m_aResults
.size();
326 while ( m_pImpl
->m_xFolderEnum
->hasMoreElements() )
330 uno::Reference
< container::XNamed
> xNamed
;
331 m_pImpl
->m_xFolderEnum
->nextElement() >>= xNamed
;
335 OSL_FAIL( "DataSupplier::getResult - Got no XNamed!" );
339 OUString aName
= xNamed
->getName();
341 if ( aName
.isEmpty() )
343 OSL_FAIL( "DataSupplier::getResult - Empty name!" );
347 // Assemble URL for child.
348 OUString aURL
= assembleChildURL( aName
);
350 m_pImpl
->m_aResults
.push_back( new ResultListEntry( aURL
) );
352 catch ( container::NoSuchElementException
const & )
354 m_pImpl
->m_bThrowException
= true;
357 catch ( lang::WrappedTargetException
const & )
359 m_pImpl
->m_bThrowException
= true;
364 m_pImpl
->m_bCountFinal
= true;
366 rtl::Reference
< ::ucbhelper::ResultSet
> xResultSet
= getResultSet().get();
367 if ( xResultSet
.is() )
372 if ( nOldCount
< m_pImpl
->m_aResults
.size() )
373 xResultSet
->rowCountChanged(
374 nOldCount
, m_pImpl
->m_aResults
.size() );
376 xResultSet
->rowCountFinal();
379 return m_pImpl
->m_aResults
.size();
384 sal_uInt32
DataSupplier::currentCount()
386 return m_pImpl
->m_aResults
.size();
391 bool DataSupplier::isCountFinal()
393 return m_pImpl
->m_bCountFinal
;
398 uno::Reference
< sdbc::XRow
> DataSupplier::queryPropertyValues(
401 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
403 if ( nIndex
< m_pImpl
->m_aResults
.size() )
405 uno::Reference
< sdbc::XRow
> xRow
= m_pImpl
->m_aResults
[ nIndex
]->xRow
;
413 if ( getResult( nIndex
) )
415 uno::Reference
< sdbc::XRow
> xRow
= Content::getPropertyValues(
417 getResultSet()->getProperties(),
418 static_cast< ContentProvider
* >(
419 m_pImpl
->m_xContent
->getProvider().get() ),
420 queryContentIdentifierString( nIndex
) );
421 m_pImpl
->m_aResults
[ nIndex
]->xRow
= xRow
;
425 return uno::Reference
< sdbc::XRow
>();
430 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex
)
432 osl::Guard
< osl::Mutex
> aGuard( m_pImpl
->m_aMutex
);
434 if ( nIndex
< m_pImpl
->m_aResults
.size() )
435 m_pImpl
->m_aResults
[ nIndex
]->xRow
= uno::Reference
< sdbc::XRow
>();
440 void DataSupplier::close()
446 void DataSupplier::validate()
447 throw( ucb::ResultSetException
)
449 if ( m_pImpl
->m_bThrowException
)
450 throw ucb::ResultSetException();
454 OUString
DataSupplier::assembleChildURL( const OUString
& aName
)
458 = m_pImpl
->m_xContent
->getIdentifier()->getContentIdentifier();
459 sal_Int32 nParam
= aContURL
.indexOf( '?' );
462 aURL
= aContURL
.copy( 0, nParam
);
464 sal_Int32 nPackageUrlEnd
= aURL
.lastIndexOf( '/' );
465 if ( nPackageUrlEnd
!= aURL
.getLength() - 1 )
468 aURL
+= ::ucb_impl::urihelper::encodeSegment( aName
);
469 aURL
+= aContURL
.copy( nParam
);
475 sal_Int32 nPackageUrlEnd
= aURL
.lastIndexOf( '/' );
476 if ( nPackageUrlEnd
!= aURL
.getLength() - 1 )
479 aURL
+= ::ucb_impl::urihelper::encodeSegment( aName
);
485 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */