Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : /**************************************************************************
31 : : TODO
32 : : **************************************************************************
33 : :
34 : : *************************************************************************/
35 : :
36 : : #include <vector>
37 : : #include <osl/diagnose.h>
38 : : #include <com/sun/star/container/XEnumeration.hpp>
39 : : #include <com/sun/star/container/XNamed.hpp>
40 : : #include <ucbhelper/contentidentifier.hxx>
41 : : #include <ucbhelper/providerhelper.hxx>
42 : : #include "pkgdatasupplier.hxx"
43 : : #include "pkgcontent.hxx"
44 : : #include "pkgprovider.hxx"
45 : :
46 : : #include "../inc/urihelper.hxx"
47 : :
48 : : using namespace com::sun::star;
49 : : using namespace package_ucp;
50 : :
51 : : namespace package_ucp
52 : : {
53 : :
54 : : //=========================================================================
55 : : //
56 : : // struct ResultListEntry.
57 : : //
58 : : //=========================================================================
59 : :
60 : 12 : struct ResultListEntry
61 : : {
62 : : rtl::OUString aURL;
63 : : uno::Reference< ucb::XContentIdentifier > xId;
64 : : uno::Reference< ucb::XContent > xContent;
65 : : uno::Reference< sdbc::XRow > xRow;
66 : :
67 : 12 : ResultListEntry( const rtl::OUString& rURL ) : aURL( rURL ) {}
68 : : };
69 : :
70 : : //=========================================================================
71 : : //
72 : : // ResultList.
73 : : //
74 : : //=========================================================================
75 : :
76 : : typedef std::vector< ResultListEntry* > ResultList;
77 : :
78 : : //=========================================================================
79 : : //
80 : : // struct DataSupplier_Impl.
81 : : //
82 : : //=========================================================================
83 : :
84 : : struct DataSupplier_Impl
85 : : {
86 : : osl::Mutex m_aMutex;
87 : : ResultList m_aResults;
88 : : rtl::Reference< Content > m_xContent;
89 : : uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
90 : : uno::Reference< container::XEnumeration > m_xFolderEnum;
91 : : sal_Int32 m_nOpenMode;
92 : : sal_Bool m_bCountFinal;
93 : : sal_Bool m_bThrowException;
94 : :
95 : 43 : 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_xFolderEnum( rContent->getIterator() ), m_nOpenMode( nOpenMode ),
101 [ + - ][ + - ]: 43 : m_bCountFinal( !m_xFolderEnum.is() ), m_bThrowException( m_bCountFinal )
102 : 43 : {}
103 : : ~DataSupplier_Impl();
104 : : };
105 : :
106 : : //=========================================================================
107 : 43 : DataSupplier_Impl::~DataSupplier_Impl()
108 : : {
109 [ + - ]: 43 : ResultList::const_iterator it = m_aResults.begin();
110 [ + - ]: 43 : ResultList::const_iterator end = m_aResults.end();
111 : :
112 [ + - ][ + + ]: 55 : while ( it != end )
113 : : {
114 [ + - ][ + - ]: 12 : delete (*it);
115 : 12 : ++it;
116 : : }
117 : 43 : }
118 : :
119 : : }
120 : :
121 : : //=========================================================================
122 : : //=========================================================================
123 : : //
124 : : // DataSupplier Implementation.
125 : : //
126 : : //=========================================================================
127 : : //=========================================================================
128 : :
129 : 43 : DataSupplier::DataSupplier(
130 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
131 : : const rtl::Reference< Content >& rContent,
132 : : sal_Int32 nOpenMode )
133 [ + - ][ + - ]: 43 : : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
134 : : {
135 : 43 : }
136 : :
137 : : //=========================================================================
138 : : // virtual
139 : 43 : DataSupplier::~DataSupplier()
140 : : {
141 [ + - ][ + - ]: 43 : delete m_pImpl;
142 [ - + ]: 86 : }
143 : :
144 : : //=========================================================================
145 : : // virtual
146 : 24 : rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
147 : : {
148 [ + - ]: 24 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
149 : :
150 [ + - ]: 24 : if ( nIndex < m_pImpl->m_aResults.size() )
151 : : {
152 : 24 : rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aURL;
153 [ + - ]: 24 : if ( !aId.isEmpty() )
154 : : {
155 : : // Already cached.
156 : 24 : return aId;
157 [ - + ]: 24 : }
158 : : }
159 : :
160 [ # # ][ # # ]: 0 : if ( getResult( nIndex ) )
161 : : {
162 : : // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
163 : 0 : return m_pImpl->m_aResults[ nIndex ]->aURL;
164 : : }
165 [ + - ]: 24 : return rtl::OUString();
166 : : }
167 : :
168 : : //=========================================================================
169 : : // virtual
170 : : uno::Reference< ucb::XContentIdentifier >
171 : 12 : DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
172 : : {
173 [ + - ]: 12 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
174 : :
175 [ + - ]: 12 : if ( nIndex < m_pImpl->m_aResults.size() )
176 : : {
177 : : uno::Reference< ucb::XContentIdentifier > xId
178 : 12 : = m_pImpl->m_aResults[ nIndex ]->xId;
179 [ - + ]: 12 : if ( xId.is() )
180 : : {
181 : : // Already cached.
182 : 12 : return xId;
183 [ + - ]: 12 : }
184 : : }
185 : :
186 [ + - ]: 12 : rtl::OUString aId = queryContentIdentifierString( nIndex );
187 [ + - ]: 12 : if ( !aId.isEmpty() )
188 : : {
189 : : uno::Reference< ucb::XContentIdentifier > xId
190 [ + - ][ + - ]: 12 : = new ::ucbhelper::ContentIdentifier( aId );
[ + - ]
191 [ + - ]: 12 : m_pImpl->m_aResults[ nIndex ]->xId = xId;
192 : 12 : return xId;
193 : : }
194 [ + - ]: 12 : return uno::Reference< ucb::XContentIdentifier >();
195 : : }
196 : :
197 : : //=========================================================================
198 : : // virtual
199 : 12 : uno::Reference< ucb::XContent > DataSupplier::queryContent(
200 : : sal_uInt32 nIndex )
201 : : {
202 [ + - ]: 12 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
203 : :
204 [ + - ]: 12 : if ( nIndex < m_pImpl->m_aResults.size() )
205 : : {
206 : : uno::Reference< ucb::XContent > xContent
207 : 12 : = m_pImpl->m_aResults[ nIndex ]->xContent;
208 [ - + ]: 12 : if ( xContent.is() )
209 : : {
210 : : // Already cached.
211 : 12 : return xContent;
212 [ + - ]: 12 : }
213 : : }
214 : :
215 : : uno::Reference< ucb::XContentIdentifier > xId
216 [ + - ]: 12 : = queryContentIdentifier( nIndex );
217 [ + - ]: 12 : if ( xId.is() )
218 : : {
219 : : try
220 : : {
221 : : uno::Reference< ucb::XContent > xContent
222 [ + - ]: 12 : = m_pImpl->m_xContent->getProvider()->queryContent( xId );
223 [ + - ]: 12 : m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
224 [ # # ]: 12 : return xContent;
225 : :
226 : : }
227 [ # # ]: 0 : catch ( ucb::IllegalIdentifierException const & )
228 : : {
229 : : }
230 : : }
231 [ + - ]: 12 : return uno::Reference< ucb::XContent >();
232 : : }
233 : :
234 : : //=========================================================================
235 : : // virtual
236 : 67 : sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
237 : : {
238 [ + - ]: 67 : osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
239 : :
240 [ + + ]: 67 : if ( m_pImpl->m_aResults.size() > nIndex )
241 : : {
242 : : // Result already present.
243 : 12 : return sal_True;
244 : : }
245 : :
246 : : // Result not (yet) present.
247 : :
248 [ - + ]: 55 : if ( m_pImpl->m_bCountFinal )
249 : 0 : return sal_False;
250 : :
251 : : // Try to obtain result...
252 : :
253 : 55 : sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
254 : 55 : sal_Bool bFound = sal_False;
255 : 55 : sal_uInt32 nPos = nOldCount;
256 : :
257 [ + - ][ + - ]: 55 : while ( m_pImpl->m_xFolderEnum->hasMoreElements() )
[ + + ]
258 : : {
259 : : try
260 : : {
261 : 12 : uno::Reference< container::XNamed > xNamed;
262 [ + - ][ + - ]: 12 : m_pImpl->m_xFolderEnum->nextElement() >>= xNamed;
[ + - ]
263 : :
264 [ - + ]: 12 : if ( !xNamed.is() )
265 : : {
266 : : OSL_FAIL( "DataSupplier::getResult - Got no XNamed!" );
267 : : break;
268 : : }
269 : :
270 [ + - ][ + - ]: 12 : rtl::OUString aName = xNamed->getName();
271 : :
272 [ - + ]: 12 : if ( aName.isEmpty() )
273 : : {
274 : : OSL_FAIL( "DataSupplier::getResult - Empty name!" );
275 : : break;
276 : : }
277 : :
278 : : // Assemble URL for child.
279 [ + - ]: 12 : rtl::OUString aURL = assembleChildURL( aName );
280 : :
281 [ + - ][ + - ]: 12 : m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
[ + - ]
282 : :
283 [ + - ]: 12 : if ( nPos == nIndex )
284 : : {
285 : : // Result obtained.
286 : 12 : bFound = sal_True;
287 : : break;
288 : : }
289 : :
290 [ + - ][ + - ]: 12 : nPos++;
[ - + ]
[ # # # ]
291 : : }
292 [ # # ]: 0 : catch ( container::NoSuchElementException const & )
293 : : {
294 : 0 : m_pImpl->m_bThrowException = sal_True;
295 : : break;
296 : : }
297 [ # # ]: 0 : catch ( lang::WrappedTargetException const & )
298 : : {
299 : 0 : m_pImpl->m_bThrowException = sal_True;
300 : : break;
301 : : }
302 : : }
303 : :
304 [ + + ]: 55 : if ( !bFound )
305 : 43 : m_pImpl->m_bCountFinal = sal_True;
306 : :
307 [ + - ]: 55 : rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
308 [ + - ]: 55 : if ( xResultSet.is() )
309 : : {
310 : : // Callbacks follow!
311 [ + - ]: 55 : aGuard.clear();
312 : :
313 [ + + ]: 55 : if ( nOldCount < m_pImpl->m_aResults.size() )
314 : : xResultSet->rowCountChanged(
315 [ + - ]: 12 : nOldCount, m_pImpl->m_aResults.size() );
316 : :
317 [ + + ]: 55 : if ( m_pImpl->m_bCountFinal )
318 [ + - ]: 43 : xResultSet->rowCountFinal();
319 : : }
320 : :
321 [ + - ]: 67 : return bFound;
322 : : }
323 : :
324 : : //=========================================================================
325 : : // virtual
326 : 0 : sal_uInt32 DataSupplier::totalCount()
327 : : {
328 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
329 : :
330 [ # # ]: 0 : if ( m_pImpl->m_bCountFinal )
331 : 0 : return m_pImpl->m_aResults.size();
332 : :
333 : 0 : sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
334 : :
335 [ # # ][ # # ]: 0 : while ( m_pImpl->m_xFolderEnum->hasMoreElements() )
[ # # ]
336 : : {
337 : : try
338 : : {
339 : 0 : uno::Reference< container::XNamed > xNamed;
340 [ # # ][ # # ]: 0 : m_pImpl->m_xFolderEnum->nextElement() >>= xNamed;
[ # # ]
341 : :
342 [ # # ]: 0 : if ( !xNamed.is() )
343 : : {
344 : : OSL_FAIL( "DataSupplier::getResult - Got no XNamed!" );
345 : : break;
346 : : }
347 : :
348 [ # # ][ # # ]: 0 : rtl::OUString aName = xNamed->getName();
349 : :
350 [ # # ]: 0 : if ( aName.isEmpty() )
351 : : {
352 : : OSL_FAIL( "DataSupplier::getResult - Empty name!" );
353 : : break;
354 : : }
355 : :
356 : : // Assemble URL for child.
357 [ # # ]: 0 : rtl::OUString aURL = assembleChildURL( aName );
358 : :
359 [ # # ][ # # ]: 0 : m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
[ # # ][ # # ]
[ # # ]
[ # # # ]
360 : : }
361 [ # # ]: 0 : catch ( container::NoSuchElementException const & )
362 : : {
363 : 0 : m_pImpl->m_bThrowException = sal_True;
364 : : break;
365 : : }
366 [ # # ]: 0 : catch ( lang::WrappedTargetException const & )
367 : : {
368 : 0 : m_pImpl->m_bThrowException = sal_True;
369 : : break;
370 : : }
371 : : }
372 : :
373 : 0 : m_pImpl->m_bCountFinal = sal_True;
374 : :
375 [ # # ]: 0 : rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
376 [ # # ]: 0 : if ( xResultSet.is() )
377 : : {
378 : : // Callbacks follow!
379 [ # # ]: 0 : aGuard.clear();
380 : :
381 [ # # ]: 0 : if ( nOldCount < m_pImpl->m_aResults.size() )
382 : : xResultSet->rowCountChanged(
383 [ # # ]: 0 : nOldCount, m_pImpl->m_aResults.size() );
384 : :
385 [ # # ]: 0 : xResultSet->rowCountFinal();
386 : : }
387 : :
388 [ # # ]: 0 : return m_pImpl->m_aResults.size();
389 : : }
390 : :
391 : : //=========================================================================
392 : : // virtual
393 : 0 : sal_uInt32 DataSupplier::currentCount()
394 : : {
395 : 0 : return m_pImpl->m_aResults.size();
396 : : }
397 : :
398 : : //=========================================================================
399 : : // virtual
400 : 0 : sal_Bool DataSupplier::isCountFinal()
401 : : {
402 : 0 : return m_pImpl->m_bCountFinal;
403 : : }
404 : :
405 : : //=========================================================================
406 : : // virtual
407 : 48 : uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues(
408 : : sal_uInt32 nIndex )
409 : : {
410 [ + - ]: 48 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
411 : :
412 [ + - ]: 48 : if ( nIndex < m_pImpl->m_aResults.size() )
413 : : {
414 : 48 : uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
415 [ + + ]: 48 : if ( xRow.is() )
416 : : {
417 : : // Already cached.
418 : 48 : return xRow;
419 [ + + ]: 48 : }
420 : : }
421 : :
422 [ + - ][ + - ]: 12 : if ( getResult( nIndex ) )
423 : : {
424 : : uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
425 : : m_pImpl->m_xSMgr,
426 [ + - ][ + - ]: 24 : getResultSet()->getProperties(),
427 : : static_cast< ContentProvider * >(
428 : 12 : m_pImpl->m_xContent->getProvider().get() ),
429 [ + - ][ + - ]: 36 : queryContentIdentifierString( nIndex ) );
430 [ + - ]: 12 : m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
431 : 12 : return xRow;
432 : : }
433 : :
434 [ + - ]: 48 : return uno::Reference< sdbc::XRow >();
435 : : }
436 : :
437 : : //=========================================================================
438 : : // virtual
439 : 0 : void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
440 : : {
441 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
442 : :
443 [ # # ]: 0 : if ( nIndex < m_pImpl->m_aResults.size() )
444 [ # # ][ # # ]: 0 : m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
445 : 0 : }
446 : :
447 : : //=========================================================================
448 : : // virtual
449 : 0 : void DataSupplier::close()
450 : : {
451 : 0 : }
452 : :
453 : : //=========================================================================
454 : : // virtual
455 : 103 : void DataSupplier::validate()
456 : : throw( ucb::ResultSetException )
457 : : {
458 [ - + ]: 103 : if ( m_pImpl->m_bThrowException )
459 [ # # ]: 0 : throw ucb::ResultSetException();
460 : 103 : }
461 : :
462 : : //=========================================================================
463 : 12 : ::rtl::OUString DataSupplier::assembleChildURL( const ::rtl::OUString& aName )
464 : : {
465 : 12 : rtl::OUString aURL;
466 : : rtl::OUString aContURL
467 [ + - ][ + - ]: 12 : = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
[ + - ]
468 : 12 : sal_Int32 nParam = aContURL.indexOf( '?' );
469 [ - + ]: 12 : if ( nParam >= 0 )
470 : : {
471 : 0 : aURL = aContURL.copy( 0, nParam );
472 : :
473 : 0 : sal_Int32 nPackageUrlEnd = aURL.lastIndexOf( '/' );
474 [ # # ]: 0 : if ( nPackageUrlEnd != aURL.getLength() - 1 )
475 : 0 : aURL += rtl::OUString("/");
476 : :
477 : 0 : aURL += ::ucb_impl::urihelper::encodeSegment( aName );
478 : 0 : aURL += aContURL.copy( nParam );
479 : : }
480 : : else
481 : : {
482 : 12 : aURL = aContURL;
483 : :
484 : 12 : sal_Int32 nPackageUrlEnd = aURL.lastIndexOf( '/' );
485 [ + - ]: 12 : if ( nPackageUrlEnd != aURL.getLength() - 1 )
486 : 12 : aURL += rtl::OUString("/");
487 : :
488 : 12 : aURL += ::ucb_impl::urihelper::encodeSegment( aName );
489 : : }
490 : 12 : return aURL;
491 : : }
492 : :
493 : :
494 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|