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 : :
38 : : #include "osl/diagnose.h"
39 : : #include "ucbhelper/contentidentifier.hxx"
40 : :
41 : : #include "tdoc_datasupplier.hxx"
42 : : #include "tdoc_content.hxx"
43 : :
44 : : using namespace com::sun::star;
45 : : using namespace tdoc_ucp;
46 : :
47 : : namespace tdoc_ucp
48 : : {
49 : :
50 : : //=========================================================================
51 : : //
52 : : // struct ResultListEntry.
53 : : //
54 : : //=========================================================================
55 : :
56 : 0 : struct ResultListEntry
57 : : {
58 : : rtl::OUString aURL;
59 : : uno::Reference< ucb::XContentIdentifier > xId;
60 : : uno::Reference< ucb::XContent > xContent;
61 : : uno::Reference< sdbc::XRow > xRow;
62 : :
63 : 0 : ResultListEntry( const rtl::OUString& rURL ) : aURL( rURL ) {}
64 : : };
65 : :
66 : : //=========================================================================
67 : : //
68 : : // ResultList.
69 : : //
70 : : //=========================================================================
71 : :
72 : : typedef std::vector< ResultListEntry* > ResultList;
73 : :
74 : : //=========================================================================
75 : : //
76 : : // struct DataSupplier_Impl.
77 : : //
78 : : //=========================================================================
79 : :
80 : : struct DataSupplier_Impl
81 : : {
82 : : osl::Mutex m_aMutex;
83 : : ResultList m_aResults;
84 : : rtl::Reference< Content > m_xContent;
85 : : uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
86 : : uno::Sequence< rtl::OUString > * m_pNamesOfChildren;
87 : : sal_Int32 m_nOpenMode;
88 : : bool m_bCountFinal;
89 : : bool m_bThrowException;
90 : :
91 : 0 : DataSupplier_Impl(
92 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
93 : : const rtl::Reference< Content >& rContent,
94 : : sal_Int32 nOpenMode )
95 : : : m_xContent( rContent ), m_xSMgr( rxSMgr ),
96 : : m_pNamesOfChildren( 0 ), m_nOpenMode( nOpenMode ),
97 [ # # ]: 0 : m_bCountFinal( false ), m_bThrowException( false )
98 : 0 : {}
99 : : ~DataSupplier_Impl();
100 : : };
101 : :
102 : : //=========================================================================
103 : 0 : DataSupplier_Impl::~DataSupplier_Impl()
104 : : {
105 [ # # ]: 0 : ResultList::const_iterator it = m_aResults.begin();
106 [ # # ]: 0 : ResultList::const_iterator end = m_aResults.end();
107 : :
108 [ # # ][ # # ]: 0 : while ( it != end )
109 : : {
110 [ # # ][ # # ]: 0 : delete (*it);
111 : 0 : ++it;
112 : : }
113 : :
114 [ # # ][ # # ]: 0 : delete m_pNamesOfChildren;
115 : 0 : }
116 : :
117 : : }
118 : :
119 : : //=========================================================================
120 : : //=========================================================================
121 : : //
122 : : // DataSupplier Implementation.
123 : : //
124 : : //=========================================================================
125 : : //=========================================================================
126 : :
127 : 0 : ResultSetDataSupplier::ResultSetDataSupplier(
128 : : const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
129 : : const rtl::Reference< Content >& rContent,
130 : : sal_Int32 nOpenMode )
131 [ # # ][ # # ]: 0 : : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
132 : : {
133 : 0 : }
134 : :
135 : : //=========================================================================
136 : : // virtual
137 : 0 : ResultSetDataSupplier::~ResultSetDataSupplier()
138 : : {
139 [ # # ][ # # ]: 0 : delete m_pImpl;
140 [ # # ]: 0 : }
141 : :
142 : : //=========================================================================
143 : : // virtual
144 : : rtl::OUString
145 : 0 : ResultSetDataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
146 : : {
147 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
148 : :
149 [ # # ]: 0 : if ( nIndex < m_pImpl->m_aResults.size() )
150 : : {
151 : 0 : rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aURL;
152 [ # # ]: 0 : if ( !aId.isEmpty() )
153 : : {
154 : : // Already cached.
155 : 0 : return aId;
156 [ # # ]: 0 : }
157 : : }
158 : :
159 [ # # ][ # # ]: 0 : if ( getResult( nIndex ) )
160 : : {
161 : : // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
162 : 0 : return m_pImpl->m_aResults[ nIndex ]->aURL;
163 : : }
164 [ # # ]: 0 : return rtl::OUString();
165 : : }
166 : :
167 : : //=========================================================================
168 : : // virtual
169 : : uno::Reference< ucb::XContentIdentifier >
170 : 0 : ResultSetDataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
171 : : {
172 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
173 : :
174 [ # # ]: 0 : if ( nIndex < m_pImpl->m_aResults.size() )
175 : : {
176 : : uno::Reference< ucb::XContentIdentifier > xId
177 : 0 : = m_pImpl->m_aResults[ nIndex ]->xId;
178 [ # # ]: 0 : if ( xId.is() )
179 : : {
180 : : // Already cached.
181 : 0 : return xId;
182 [ # # ]: 0 : }
183 : : }
184 : :
185 [ # # ]: 0 : rtl::OUString aId = queryContentIdentifierString( nIndex );
186 [ # # ]: 0 : if ( !aId.isEmpty() )
187 : : {
188 : : uno::Reference< ucb::XContentIdentifier > xId
189 [ # # ][ # # ]: 0 : = new ::ucbhelper::ContentIdentifier( aId );
[ # # ]
190 [ # # ]: 0 : m_pImpl->m_aResults[ nIndex ]->xId = xId;
191 : 0 : return xId;
192 : : }
193 [ # # ]: 0 : return uno::Reference< ucb::XContentIdentifier >();
194 : : }
195 : :
196 : : //=========================================================================
197 : : // virtual
198 : : uno::Reference< ucb::XContent >
199 : 0 : ResultSetDataSupplier::queryContent( sal_uInt32 nIndex )
200 : : {
201 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
202 : :
203 [ # # ]: 0 : if ( nIndex < m_pImpl->m_aResults.size() )
204 : : {
205 : : uno::Reference< ucb::XContent > xContent
206 : 0 : = m_pImpl->m_aResults[ nIndex ]->xContent;
207 [ # # ]: 0 : if ( xContent.is() )
208 : : {
209 : : // Already cached.
210 : 0 : return xContent;
211 [ # # ]: 0 : }
212 : : }
213 : :
214 : : uno::Reference< ucb::XContentIdentifier > xId
215 [ # # ]: 0 : = queryContentIdentifier( nIndex );
216 [ # # ]: 0 : if ( xId.is() )
217 : : {
218 : : try
219 : : {
220 : : uno::Reference< ucb::XContent > xContent
221 [ # # ]: 0 : = m_pImpl->m_xContent->getProvider()->queryContent( xId );
222 [ # # ]: 0 : m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
223 [ # # ]: 0 : return xContent;
224 : :
225 : : }
226 [ # # ]: 0 : catch ( ucb::IllegalIdentifierException const & )
227 : : {
228 : : }
229 : : }
230 [ # # ]: 0 : return uno::Reference< ucb::XContent >();
231 : : }
232 : :
233 : : //=========================================================================
234 : : // virtual
235 : 0 : sal_Bool ResultSetDataSupplier::getResult( sal_uInt32 nIndex )
236 : : {
237 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
238 : :
239 [ # # ]: 0 : if ( m_pImpl->m_aResults.size() > nIndex )
240 : : {
241 : : // Result already present.
242 : 0 : return sal_True;
243 : : }
244 : :
245 : : // Result not (yet) present.
246 : :
247 [ # # ]: 0 : if ( m_pImpl->m_bCountFinal )
248 : 0 : return sal_False;
249 : :
250 : : // Try to obtain result...
251 : :
252 : 0 : sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
253 : 0 : bool bFound = false;
254 : :
255 [ # # ][ # # ]: 0 : if ( queryNamesOfChildren() )
256 : : {
257 [ # # ]: 0 : for ( sal_uInt32 n = nOldCount;
258 : : n < sal::static_int_cast<sal_uInt32>(
259 : 0 : m_pImpl->m_pNamesOfChildren->getLength());
260 : : ++n )
261 : : {
262 : : const rtl::OUString & rName
263 : 0 : = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
264 : :
265 [ # # ]: 0 : if ( rName.isEmpty() )
266 : : {
267 : : OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
268 : : break;
269 : : }
270 : :
271 : : // Assemble URL for child.
272 [ # # ]: 0 : rtl::OUString aURL = assembleChildURL( rName );
273 : :
274 [ # # ][ # # ]: 0 : m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
[ # # ]
275 : :
276 [ # # ]: 0 : if ( n == nIndex )
277 : : {
278 : : // Result obtained.
279 : 0 : bFound = true;
280 : : break;
281 : : }
282 [ # # ]: 0 : }
283 : : }
284 : :
285 [ # # ]: 0 : if ( !bFound )
286 : 0 : m_pImpl->m_bCountFinal = sal_True;
287 : :
288 [ # # ]: 0 : rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
289 [ # # ]: 0 : if ( xResultSet.is() )
290 : : {
291 : : // Callbacks follow!
292 [ # # ]: 0 : aGuard.clear();
293 : :
294 [ # # ]: 0 : if ( nOldCount < m_pImpl->m_aResults.size() )
295 [ # # ]: 0 : xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
296 : :
297 [ # # ]: 0 : if ( m_pImpl->m_bCountFinal )
298 [ # # ]: 0 : xResultSet->rowCountFinal();
299 : : }
300 : :
301 [ # # ]: 0 : return bFound;
302 : : }
303 : :
304 : : //=========================================================================
305 : : // virtual
306 : 0 : sal_uInt32 ResultSetDataSupplier::totalCount()
307 : : {
308 [ # # ]: 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
309 : :
310 [ # # ]: 0 : if ( m_pImpl->m_bCountFinal )
311 : 0 : return m_pImpl->m_aResults.size();
312 : :
313 : 0 : sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
314 : :
315 [ # # ][ # # ]: 0 : if ( queryNamesOfChildren() )
316 : : {
317 [ # # ]: 0 : for ( sal_uInt32 n = nOldCount;
318 : : n < sal::static_int_cast<sal_uInt32>(
319 : 0 : m_pImpl->m_pNamesOfChildren->getLength());
320 : : ++n )
321 : : {
322 : : const rtl::OUString & rName
323 : 0 : = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
324 : :
325 [ # # ]: 0 : if ( rName.isEmpty() )
326 : : {
327 : : OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
328 : : break;
329 : : }
330 : :
331 : : // Assemble URL for child.
332 [ # # ]: 0 : rtl::OUString aURL = assembleChildURL( rName );
333 : :
334 [ # # ][ # # ]: 0 : m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
[ # # ]
335 : 0 : }
336 : : }
337 : :
338 : 0 : m_pImpl->m_bCountFinal = sal_True;
339 : :
340 [ # # ]: 0 : rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
341 [ # # ]: 0 : if ( xResultSet.is() )
342 : : {
343 : : // Callbacks follow!
344 [ # # ]: 0 : aGuard.clear();
345 : :
346 [ # # ]: 0 : if ( nOldCount < m_pImpl->m_aResults.size() )
347 [ # # ]: 0 : xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
348 : :
349 [ # # ]: 0 : xResultSet->rowCountFinal();
350 : : }
351 : :
352 [ # # ]: 0 : return m_pImpl->m_aResults.size();
353 : : }
354 : :
355 : : //=========================================================================
356 : : // virtual
357 : 0 : sal_uInt32 ResultSetDataSupplier::currentCount()
358 : : {
359 : 0 : return m_pImpl->m_aResults.size();
360 : : }
361 : :
362 : : //=========================================================================
363 : : // virtual
364 : 0 : sal_Bool ResultSetDataSupplier::isCountFinal()
365 : : {
366 : 0 : return m_pImpl->m_bCountFinal;
367 : : }
368 : :
369 : : //=========================================================================
370 : : // virtual
371 : : uno::Reference< sdbc::XRow >
372 : 0 : ResultSetDataSupplier::queryPropertyValues( sal_uInt32 nIndex )
373 : : {
374 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
375 : :
376 [ # # ]: 0 : if ( nIndex < m_pImpl->m_aResults.size() )
377 : : {
378 : 0 : uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
379 [ # # ]: 0 : if ( xRow.is() )
380 : : {
381 : : // Already cached.
382 : 0 : return xRow;
383 [ # # ]: 0 : }
384 : : }
385 : :
386 [ # # ][ # # ]: 0 : if ( getResult( nIndex ) )
387 : : {
388 : : uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
389 : : m_pImpl->m_xSMgr,
390 [ # # ][ # # ]: 0 : getResultSet()->getProperties(),
391 : : m_pImpl->m_xContent->getContentProvider().get(),
392 [ # # ][ # # ]: 0 : queryContentIdentifierString( nIndex ) );
[ # # ]
393 [ # # ]: 0 : m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
394 : 0 : return xRow;
395 : : }
396 : :
397 [ # # ]: 0 : return uno::Reference< sdbc::XRow >();
398 : : }
399 : :
400 : : //=========================================================================
401 : : // virtual
402 : 0 : void ResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
403 : : {
404 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
405 : :
406 [ # # ]: 0 : if ( nIndex < m_pImpl->m_aResults.size() )
407 [ # # ][ # # ]: 0 : m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
408 : 0 : }
409 : :
410 : : //=========================================================================
411 : : // virtual
412 : 0 : void ResultSetDataSupplier::close()
413 : : {
414 : 0 : }
415 : :
416 : : //=========================================================================
417 : : // virtual
418 : 0 : void ResultSetDataSupplier::validate()
419 : : throw( ucb::ResultSetException )
420 : : {
421 [ # # ]: 0 : if ( m_pImpl->m_bThrowException )
422 [ # # ]: 0 : throw ucb::ResultSetException();
423 : 0 : }
424 : :
425 : : //=========================================================================
426 : 0 : bool ResultSetDataSupplier::queryNamesOfChildren()
427 : : {
428 [ # # ]: 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
429 : :
430 [ # # ]: 0 : if ( m_pImpl->m_pNamesOfChildren == 0 )
431 : : {
432 : : uno::Sequence< rtl::OUString > * pNamesOfChildren
433 [ # # ]: 0 : = new uno::Sequence< rtl::OUString >();
434 : :
435 [ # # ]: 0 : if ( !m_pImpl->m_xContent->getContentProvider()->queryNamesOfChildren(
436 [ # # ][ # # ]: 0 : m_pImpl->m_xContent->getIdentifier()->getContentIdentifier(),
437 [ # # ][ # # ]: 0 : *pNamesOfChildren ) )
[ # # ]
438 : : {
439 : : OSL_FAIL( "Got no list of children!" );
440 : 0 : m_pImpl->m_bThrowException = sal_True;
441 : 0 : return false;
442 : : }
443 : : else
444 : : {
445 : 0 : m_pImpl->m_pNamesOfChildren = pNamesOfChildren;
446 : : }
447 : : }
448 [ # # ]: 0 : return true;
449 : : }
450 : :
451 : : //=========================================================================
452 : : ::rtl::OUString
453 : 0 : ResultSetDataSupplier::assembleChildURL( const ::rtl::OUString& aName )
454 : : {
455 : : rtl::OUString aContURL
456 [ # # ][ # # ]: 0 : = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
[ # # ]
457 : 0 : rtl::OUString aURL( aContURL );
458 : :
459 : 0 : sal_Int32 nUrlEnd = aURL.lastIndexOf( '/' );
460 [ # # ]: 0 : if ( nUrlEnd != aURL.getLength() - 1 )
461 : 0 : aURL += rtl::OUString("/");
462 : :
463 : 0 : aURL += aName;
464 : 0 : return aURL;
465 : : }
466 : :
467 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|