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 : OUString aURL;
50 : uno::Reference< ucb::XContentIdentifier > xId;
51 : uno::Reference< ucb::XContent > xContent;
52 : uno::Reference< sdbc::XRow > xRow;
53 :
54 0 : explicit ResultListEntry( const 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< 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 : // DataSupplier Implementation.
111 0 : ResultSetDataSupplier::ResultSetDataSupplier(
112 : const uno::Reference< uno::XComponentContext >& rxContext,
113 : const rtl::Reference< Content >& rContent,
114 : sal_Int32 nOpenMode )
115 0 : : m_pImpl( new DataSupplier_Impl( rxContext, rContent, nOpenMode ) )
116 : {
117 0 : }
118 :
119 : // virtual
120 0 : ResultSetDataSupplier::~ResultSetDataSupplier()
121 : {
122 0 : delete m_pImpl;
123 0 : }
124 :
125 : // virtual
126 : OUString
127 0 : ResultSetDataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
128 : {
129 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
130 :
131 0 : if ( nIndex < m_pImpl->m_aResults.size() )
132 : {
133 0 : OUString aId = m_pImpl->m_aResults[ nIndex ]->aURL;
134 0 : if ( !aId.isEmpty() )
135 : {
136 : // Already cached.
137 0 : return aId;
138 0 : }
139 : }
140 :
141 0 : if ( getResult( nIndex ) )
142 : {
143 : // Note: getResult fills m_pImpl->m_aResults[ nIndex ]->aURL.
144 0 : return m_pImpl->m_aResults[ nIndex ]->aURL;
145 : }
146 0 : return OUString();
147 : }
148 :
149 : // virtual
150 : uno::Reference< ucb::XContentIdentifier >
151 0 : ResultSetDataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
152 : {
153 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
154 :
155 0 : if ( nIndex < m_pImpl->m_aResults.size() )
156 : {
157 : uno::Reference< ucb::XContentIdentifier > xId
158 0 : = m_pImpl->m_aResults[ nIndex ]->xId;
159 0 : if ( xId.is() )
160 : {
161 : // Already cached.
162 0 : return xId;
163 0 : }
164 : }
165 :
166 0 : OUString aId = queryContentIdentifierString( nIndex );
167 0 : if ( !aId.isEmpty() )
168 : {
169 : uno::Reference< ucb::XContentIdentifier > xId
170 0 : = new ::ucbhelper::ContentIdentifier( aId );
171 0 : m_pImpl->m_aResults[ nIndex ]->xId = xId;
172 0 : return xId;
173 : }
174 0 : return uno::Reference< ucb::XContentIdentifier >();
175 : }
176 :
177 : // virtual
178 : uno::Reference< ucb::XContent >
179 0 : ResultSetDataSupplier::queryContent( sal_uInt32 nIndex )
180 : {
181 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
182 :
183 0 : if ( nIndex < m_pImpl->m_aResults.size() )
184 : {
185 : uno::Reference< ucb::XContent > xContent
186 0 : = m_pImpl->m_aResults[ nIndex ]->xContent;
187 0 : if ( xContent.is() )
188 : {
189 : // Already cached.
190 0 : return xContent;
191 0 : }
192 : }
193 :
194 : uno::Reference< ucb::XContentIdentifier > xId
195 0 : = queryContentIdentifier( nIndex );
196 0 : if ( xId.is() )
197 : {
198 : try
199 : {
200 : uno::Reference< ucb::XContent > xContent
201 0 : = m_pImpl->m_xContent->getProvider()->queryContent( xId );
202 0 : m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
203 0 : return xContent;
204 :
205 : }
206 0 : catch ( ucb::IllegalIdentifierException const & )
207 : {
208 : }
209 : }
210 0 : return uno::Reference< ucb::XContent >();
211 : }
212 :
213 : // virtual
214 0 : bool ResultSetDataSupplier::getResult( sal_uInt32 nIndex )
215 : {
216 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
217 :
218 0 : if ( m_pImpl->m_aResults.size() > nIndex )
219 : {
220 : // Result already present.
221 0 : return true;
222 : }
223 :
224 : // Result not (yet) present.
225 :
226 0 : if ( m_pImpl->m_bCountFinal )
227 0 : return false;
228 :
229 : // Try to obtain result...
230 :
231 0 : sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
232 0 : bool bFound = false;
233 :
234 0 : if ( queryNamesOfChildren() )
235 : {
236 0 : for ( sal_uInt32 n = nOldCount;
237 : n < sal::static_int_cast<sal_uInt32>(
238 0 : m_pImpl->m_pNamesOfChildren->getLength());
239 : ++n )
240 : {
241 : const OUString & rName
242 0 : = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
243 :
244 0 : if ( rName.isEmpty() )
245 : {
246 : OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
247 0 : break;
248 : }
249 :
250 : // Assemble URL for child.
251 0 : OUString aURL = assembleChildURL( rName );
252 :
253 0 : m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
254 :
255 0 : if ( n == nIndex )
256 : {
257 : // Result obtained.
258 0 : bFound = true;
259 0 : break;
260 : }
261 0 : }
262 : }
263 :
264 0 : if ( !bFound )
265 0 : m_pImpl->m_bCountFinal = true;
266 :
267 0 : rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
268 0 : if ( xResultSet.is() )
269 : {
270 : // Callbacks follow!
271 0 : aGuard.clear();
272 :
273 0 : if ( nOldCount < m_pImpl->m_aResults.size() )
274 0 : xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
275 :
276 0 : if ( m_pImpl->m_bCountFinal )
277 0 : xResultSet->rowCountFinal();
278 : }
279 :
280 0 : return bFound;
281 : }
282 :
283 : // virtual
284 0 : sal_uInt32 ResultSetDataSupplier::totalCount()
285 : {
286 0 : osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
287 :
288 0 : if ( m_pImpl->m_bCountFinal )
289 0 : return m_pImpl->m_aResults.size();
290 :
291 0 : sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
292 :
293 0 : if ( queryNamesOfChildren() )
294 : {
295 0 : for ( sal_uInt32 n = nOldCount;
296 : n < sal::static_int_cast<sal_uInt32>(
297 0 : m_pImpl->m_pNamesOfChildren->getLength());
298 : ++n )
299 : {
300 : const OUString & rName
301 0 : = m_pImpl->m_pNamesOfChildren->getConstArray()[ n ];
302 :
303 0 : if ( rName.isEmpty() )
304 : {
305 : OSL_FAIL( "ResultDataSupplier::getResult - Empty name!" );
306 0 : break;
307 : }
308 :
309 : // Assemble URL for child.
310 0 : OUString aURL = assembleChildURL( rName );
311 :
312 0 : m_pImpl->m_aResults.push_back( new ResultListEntry( aURL ) );
313 0 : }
314 : }
315 :
316 0 : m_pImpl->m_bCountFinal = true;
317 :
318 0 : rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
319 0 : if ( xResultSet.is() )
320 : {
321 : // Callbacks follow!
322 0 : aGuard.clear();
323 :
324 0 : if ( nOldCount < m_pImpl->m_aResults.size() )
325 0 : xResultSet->rowCountChanged( nOldCount, m_pImpl->m_aResults.size() );
326 :
327 0 : xResultSet->rowCountFinal();
328 : }
329 :
330 0 : return m_pImpl->m_aResults.size();
331 : }
332 :
333 : // virtual
334 0 : sal_uInt32 ResultSetDataSupplier::currentCount()
335 : {
336 0 : return m_pImpl->m_aResults.size();
337 : }
338 :
339 : // virtual
340 0 : bool ResultSetDataSupplier::isCountFinal()
341 : {
342 0 : return m_pImpl->m_bCountFinal;
343 : }
344 :
345 : // virtual
346 : uno::Reference< sdbc::XRow >
347 0 : ResultSetDataSupplier::queryPropertyValues( sal_uInt32 nIndex )
348 : {
349 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
350 :
351 0 : if ( nIndex < m_pImpl->m_aResults.size() )
352 : {
353 0 : uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
354 0 : if ( xRow.is() )
355 : {
356 : // Already cached.
357 0 : return xRow;
358 0 : }
359 : }
360 :
361 0 : if ( getResult( nIndex ) )
362 : {
363 : uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
364 : m_pImpl->m_xContext,
365 0 : getResultSet()->getProperties(),
366 : m_pImpl->m_xContent->getContentProvider().get(),
367 0 : queryContentIdentifierString( nIndex ) );
368 0 : m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
369 0 : return xRow;
370 : }
371 :
372 0 : return uno::Reference< sdbc::XRow >();
373 : }
374 :
375 : // virtual
376 0 : void ResultSetDataSupplier::releasePropertyValues( sal_uInt32 nIndex )
377 : {
378 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
379 :
380 0 : if ( nIndex < m_pImpl->m_aResults.size() )
381 0 : m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
382 0 : }
383 :
384 : // virtual
385 0 : void ResultSetDataSupplier::close()
386 : {
387 0 : }
388 :
389 : // virtual
390 0 : void ResultSetDataSupplier::validate()
391 : throw( ucb::ResultSetException )
392 : {
393 0 : if ( m_pImpl->m_bThrowException )
394 0 : throw ucb::ResultSetException();
395 0 : }
396 :
397 0 : bool ResultSetDataSupplier::queryNamesOfChildren()
398 : {
399 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
400 :
401 0 : if ( m_pImpl->m_pNamesOfChildren == 0 )
402 : {
403 : uno::Sequence< OUString > * pNamesOfChildren
404 0 : = new uno::Sequence< OUString >();
405 :
406 0 : if ( !m_pImpl->m_xContent->getContentProvider()->queryNamesOfChildren(
407 0 : m_pImpl->m_xContent->getIdentifier()->getContentIdentifier(),
408 0 : *pNamesOfChildren ) )
409 : {
410 : OSL_FAIL( "Got no list of children!" );
411 0 : delete pNamesOfChildren;
412 0 : m_pImpl->m_bThrowException = true;
413 0 : return false;
414 : }
415 : else
416 : {
417 0 : m_pImpl->m_pNamesOfChildren = pNamesOfChildren;
418 : }
419 : }
420 0 : return true;
421 : }
422 :
423 : OUString
424 0 : ResultSetDataSupplier::assembleChildURL( const OUString& aName )
425 : {
426 : OUString aContURL
427 0 : = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
428 0 : OUString aURL( aContURL );
429 :
430 0 : sal_Int32 nUrlEnd = aURL.lastIndexOf( '/' );
431 0 : if ( nUrlEnd != aURL.getLength() - 1 )
432 0 : aURL += "/";
433 :
434 0 : aURL += aName;
435 0 : return aURL;
436 : }
437 :
438 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|