1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_ucbhelper.hxx"
26
27 /**************************************************************************
28 TODO
29 **************************************************************************
30
31 *************************************************************************/
32
33 #include <vector>
34
35 #include "ucbhelper/contentidentifier.hxx"
36 #include "ucbhelper/providerhelper.hxx"
37
38 #include "myucp_datasupplier.hxx"
39 #include "myucp_content.hxx"
40
41 using namespace com::sun::star;
42
43 // @@@ Adjust namespace name.
44 namespace myucp
45 {
46
47 //=========================================================================
48 //
49 // struct ResultListEntry.
50 //
51 //=========================================================================
52
53 struct ResultListEntry
54 {
55 rtl::OUString aId;
56 uno::Reference< ucb::XContentIdentifier > xId;
57 uno::Reference< ucb::XContent > xContent;
58 uno::Reference< sdbc::XRow > xRow;
59 const ContentProperties& rData;
60
ResultListEntrymyucp::ResultListEntry61 ResultListEntry( const ContentProperties& rEntry ) : rData( rEntry ) {}
62 };
63
64 //=========================================================================
65 //
66 // ResultList.
67 //
68 //=========================================================================
69
70 typedef std::vector< ResultListEntry* > ResultList;
71
72 //=========================================================================
73 //
74 // struct DataSupplier_Impl.
75 //
76 //=========================================================================
77
78 struct DataSupplier_Impl
79 {
80 osl::Mutex m_aMutex;
81 ResultList m_aResults;
82 rtl::Reference< Content > m_xContent;
83 uno::Reference< lang::XMultiServiceFactory > m_xSMgr;
84 // @@@ The data source and an iterator for it
85 // Entry m_aFolder;
86 // Entry::iterator m_aIterator;
87 sal_Int32 m_nOpenMode;
88 sal_Bool m_bCountFinal;
89
DataSupplier_Implmyucp::DataSupplier_Impl90 DataSupplier_Impl( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
91 const rtl::Reference< Content >& rContent,
92 sal_Int32 nOpenMode )
93 : m_xContent( rContent ), m_xSMgr( rxSMgr ),
94 // m_aFolder( rxSMgr, rContent->getIdentifier()->getContentIdentifier() ),
95 m_nOpenMode( nOpenMode ), m_bCountFinal( sal_False ) {}
96 ~DataSupplier_Impl();
97 };
98
99 //=========================================================================
~DataSupplier_Impl()100 DataSupplier_Impl::~DataSupplier_Impl()
101 {
102 ResultList::const_iterator it = m_aResults.begin();
103 ResultList::const_iterator end = m_aResults.end();
104
105 while ( it != end )
106 {
107 delete (*it);
108 it++;
109 }
110 }
111
112 //=========================================================================
113 //=========================================================================
114 //
115 // DataSupplier Implementation.
116 //
117 //=========================================================================
118 //=========================================================================
119
DataSupplier(const uno::Reference<lang::XMultiServiceFactory> & rxSMgr,const rtl::Reference<Content> & rContent,sal_Int32 nOpenMode)120 DataSupplier::DataSupplier( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
121 const rtl::Reference< Content >& rContent,
122 sal_Int32 nOpenMode )
123 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
124 {
125 }
126
127 //=========================================================================
128 // virtual
~DataSupplier()129 DataSupplier::~DataSupplier()
130 {
131 delete m_pImpl;
132 }
133
134 //=========================================================================
135 // virtual
queryContentIdentifierString(sal_uInt32 nIndex)136 rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
137 {
138 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
139
140 if ( nIndex < m_pImpl->m_aResults.size() )
141 {
142 rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
143 if ( aId.getLength() )
144 {
145 // Already cached.
146 return aId;
147 }
148 }
149
150 if ( getResult( nIndex ) )
151 {
152 rtl::OUString aId
153 = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
154
155 aId += m_pImpl->m_aResults[ nIndex ]->rData.aTitle;
156
157 m_pImpl->m_aResults[ nIndex ]->aId = aId;
158 return aId;
159 }
160 return rtl::OUString();
161 }
162
163 //=========================================================================
164 // virtual
165 uno::Reference< ucb::XContentIdentifier >
queryContentIdentifier(sal_uInt32 nIndex)166 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
167 {
168 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
169
170 if ( nIndex < m_pImpl->m_aResults.size() )
171 {
172 uno::Reference< ucb::XContentIdentifier > xId
173 = m_pImpl->m_aResults[ nIndex ]->xId;
174 if ( xId.is() )
175 {
176 // Already cached.
177 return xId;
178 }
179 }
180
181 rtl::OUString aId = queryContentIdentifierString( nIndex );
182 if ( aId.getLength() )
183 {
184 uno::Reference< ucb::XContentIdentifier > xId
185 = new ::ucbhelper::ContentIdentifier( aId );
186 m_pImpl->m_aResults[ nIndex ]->xId = xId;
187 return xId;
188 }
189 return uno::Reference< ucb::XContentIdentifier >();
190 }
191
192 //=========================================================================
193 // virtual
194 uno::Reference< ucb::XContent >
queryContent(sal_uInt32 nIndex)195 DataSupplier::queryContent( sal_uInt32 nIndex )
196 {
197 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
198
199 if ( nIndex < m_pImpl->m_aResults.size() )
200 {
201 uno::Reference< ucb::XContent > xContent
202 = m_pImpl->m_aResults[ nIndex ]->xContent;
203 if ( xContent.is() )
204 {
205 // Already cached.
206 return xContent;
207 }
208 }
209
210 uno::Reference< ucb::XContentIdentifier > xId
211 = queryContentIdentifier( nIndex );
212 if ( xId.is() )
213 {
214 try
215 {
216 uno::Reference< ucb::XContent > xContent
217 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
218 m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
219 return xContent;
220
221 }
222 catch ( ucb::IllegalIdentifierException& )
223 {
224 }
225 }
226 return uno::Reference< ucb::XContent >();
227 }
228
229 //=========================================================================
230 // virtual
getResult(sal_uInt32 nIndex)231 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
232 {
233 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
234
235 if ( m_pImpl->m_aResults.size() > nIndex )
236 {
237 // Result already present.
238 return sal_True;
239 }
240
241 // Result not (yet) present.
242
243 if ( m_pImpl->m_bCountFinal )
244 return sal_False;
245
246 // Try to obtain result...
247
248 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
249 sal_Bool bFound = sal_False;
250
251 // @@@ Obtain data and put it into result list...
252 /*
253 sal_uInt32 nPos = nOldCount;
254 while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
255 {
256 m_pImpl->m_aResults.push_back(
257 new ResultListEntry( *m_pImpl->m_aIterator ) );
258
259 if ( nPos == nIndex )
260 {
261 // Result obtained.
262 bFound = sal_True;
263 break;
264 }
265
266 nPos++;
267 }
268 */
269
270 if ( !bFound )
271 m_pImpl->m_bCountFinal = sal_True;
272
273 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
274 if ( xResultSet.is() )
275 {
276 // Callbacks follow!
277 aGuard.clear();
278
279 if ( nOldCount < m_pImpl->m_aResults.size() )
280 xResultSet->rowCountChanged(
281 nOldCount, m_pImpl->m_aResults.size() );
282
283 if ( m_pImpl->m_bCountFinal )
284 xResultSet->rowCountFinal();
285 }
286
287 return bFound;
288 }
289
290 //=========================================================================
291 // virtual
totalCount()292 sal_uInt32 DataSupplier::totalCount()
293 {
294 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
295
296 if ( m_pImpl->m_bCountFinal )
297 return m_pImpl->m_aResults.size();
298
299 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
300
301 // @@@ Obtain data and put it into result list...
302 /*
303 while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
304 m_pImpl->m_aResults.push_back(
305 new ResultListEntry( *m_pImpl->m_aIterator ) );
306 */
307 m_pImpl->m_bCountFinal = sal_True;
308
309 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
310 if ( xResultSet.is() )
311 {
312 // Callbacks follow!
313 aGuard.clear();
314
315 if ( nOldCount < m_pImpl->m_aResults.size() )
316 xResultSet->rowCountChanged(
317 nOldCount, m_pImpl->m_aResults.size() );
318
319 xResultSet->rowCountFinal();
320 }
321
322 return m_pImpl->m_aResults.size();
323 }
324
325 //=========================================================================
326 // virtual
currentCount()327 sal_uInt32 DataSupplier::currentCount()
328 {
329 return m_pImpl->m_aResults.size();
330 }
331
332 //=========================================================================
333 // virtual
isCountFinal()334 sal_Bool DataSupplier::isCountFinal()
335 {
336 return m_pImpl->m_bCountFinal;
337 }
338
339 //=========================================================================
340 // virtual
341 uno::Reference< sdbc::XRow >
queryPropertyValues(sal_uInt32 nIndex)342 DataSupplier::queryPropertyValues( sal_uInt32 nIndex )
343 {
344 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
345
346 if ( nIndex < m_pImpl->m_aResults.size() )
347 {
348 uno::Reference< sdbc::XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
349 if ( xRow.is() )
350 {
351 // Already cached.
352 return xRow;
353 }
354 }
355
356 if ( getResult( nIndex ) )
357 {
358 uno::Reference< sdbc::XRow > xRow = Content::getPropertyValues(
359 m_pImpl->m_xSMgr,
360 getResultSet()->getProperties(),
361 m_pImpl->m_aResults[ nIndex ]->rData,
362 m_pImpl->m_xContent->getProvider().get(),
363 queryContentIdentifierString( nIndex ) );
364 m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
365 return xRow;
366 }
367
368 return uno::Reference< sdbc::XRow >();
369 }
370
371 //=========================================================================
372 // virtual
releasePropertyValues(sal_uInt32 nIndex)373 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
374 {
375 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
376
377 if ( nIndex < m_pImpl->m_aResults.size() )
378 m_pImpl->m_aResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
379 }
380
381 //=========================================================================
382 // virtual
close()383 void DataSupplier::close()
384 {
385 }
386
387 //=========================================================================
388 // virtual
validate()389 void DataSupplier::validate()
390 throw( ucb::ResultSetException )
391 {
392 }
393
394 } // namespace
395