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