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_dbaccess.hxx"
26
27 /**************************************************************************
28 TODO
29 **************************************************************************
30
31 *************************************************************************/
32
33 #include <vector>
34
35 #ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX
36 #include <ucbhelper/contentidentifier.hxx>
37 #endif
38 #ifndef _UCBHELPER_PROVIDERHELPER_HXX
39 #include <ucbhelper/providerhelper.hxx>
40 #endif
41
42 #ifndef DBA_DATASUPPLIER_HXX
43 #include "myucp_datasupplier.hxx"
44 #endif
45 #ifndef DBA_CONTENTHELPER_HXX
46 #include "ContentHelper.hxx"
47 #endif
48 #ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMEACCESS_HPP_
49 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
50 #endif
51 #ifndef _TOOLS_DEBUG_HXX
52 #include <tools/debug.hxx>
53 #endif
54
55 using namespace ::com::sun::star::uno;
56 using namespace ::com::sun::star::ucb;
57 using namespace ::com::sun::star::beans;
58 using namespace ::com::sun::star::lang;
59 using namespace ::com::sun::star::sdbc;
60 using namespace ::com::sun::star::io;
61 using namespace ::com::sun::star::container;
62
63 // @@@ Adjust namespace name.
64 using namespace dbaccess;
65
66 // @@@ Adjust namespace name.
67 namespace dbaccess
68 {
69
70 //=========================================================================
71 //
72 // struct ResultListEntry.
73 //
74 //=========================================================================
75
76 struct ResultListEntry
77 {
78 rtl::OUString aId;
79 Reference< XContentIdentifier > xId;
80 ::rtl::Reference< OContentHelper > xContent;
81 Reference< XRow > xRow;
82 const ContentProperties& rData;
83
ResultListEntrydbaccess::ResultListEntry84 ResultListEntry( const ContentProperties& rEntry ) : rData( rEntry ) {}
85 };
86
87 //=========================================================================
88 //
89 // ResultList.
90 //
91 //=========================================================================
92
93 typedef std::vector< ResultListEntry* > ResultList;
94
95 //=========================================================================
96 //
97 // struct DataSupplier_Impl.
98 //
99 //=========================================================================
100
101 struct DataSupplier_Impl
102 {
103 osl::Mutex m_aMutex;
104 ResultList m_aResults;
105 rtl::Reference< ODocumentContainer > m_xContent;
106 Reference< XMultiServiceFactory > m_xSMgr;
107 sal_Int32 m_nOpenMode;
108 sal_Bool m_bCountFinal;
109
DataSupplier_Impldbaccess::DataSupplier_Impl110 DataSupplier_Impl( const Reference< XMultiServiceFactory >& rxSMgr,
111 const rtl::Reference< ODocumentContainer >& rContent,
112 sal_Int32 nOpenMode )
113 : m_xContent(rContent)
114 , m_xSMgr( rxSMgr )
115 , m_nOpenMode( nOpenMode )
116 , m_bCountFinal( sal_False ) {}
117 ~DataSupplier_Impl();
118 };
119
120 //=========================================================================
~DataSupplier_Impl()121 DataSupplier_Impl::~DataSupplier_Impl()
122 {
123 ResultList::const_iterator it = m_aResults.begin();
124 ResultList::const_iterator end = m_aResults.end();
125
126 while ( it != end )
127 {
128 delete (*it);
129 it++;
130 }
131 }
132
133 }
134
135 //=========================================================================
136 //=========================================================================
137 //
138 // DataSupplier Implementation.
139 //
140 //=========================================================================
141 //=========================================================================
DBG_NAME(DataSupplier)142 DBG_NAME(DataSupplier)
143
144 DataSupplier::DataSupplier( const Reference< XMultiServiceFactory >& rxSMgr,
145 const rtl::Reference< ODocumentContainer >& rContent,
146 sal_Int32 nOpenMode )
147 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent,nOpenMode ) )
148 {
149 DBG_CTOR(DataSupplier,NULL);
150
151 }
152
153 //=========================================================================
154 // virtual
~DataSupplier()155 DataSupplier::~DataSupplier()
156 {
157
158 DBG_DTOR(DataSupplier,NULL);
159 }
160
161 //=========================================================================
162 // virtual
queryContentIdentifierString(sal_uInt32 nIndex)163 rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
164 {
165 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
166
167 if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
168 {
169 rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
170 if ( aId.getLength() )
171 {
172 // Already cached.
173 return aId;
174 }
175 }
176
177 if ( getResult( nIndex ) )
178 {
179 rtl::OUString aId
180 = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
181
182 if ( aId.getLength() )
183 aId += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
184
185 aId += m_pImpl->m_aResults[ nIndex ]->rData.aTitle;
186
187 m_pImpl->m_aResults[ nIndex ]->aId = aId;
188 return aId;
189 }
190 return rtl::OUString();
191 }
192
193 //=========================================================================
194 // virtual
195 Reference< XContentIdentifier >
queryContentIdentifier(sal_uInt32 nIndex)196 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
197 {
198 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
199
200 if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
201 {
202 Reference< XContentIdentifier > xId = m_pImpl->m_aResults[ nIndex ]->xId;
203 if ( xId.is() )
204 {
205 // Already cached.
206 return xId;
207 }
208 }
209
210 rtl::OUString aId = queryContentIdentifierString( nIndex );
211 if ( aId.getLength() )
212 {
213 Reference< XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( aId );
214 m_pImpl->m_aResults[ nIndex ]->xId = xId;
215 return xId;
216 }
217 return Reference< XContentIdentifier >();
218 }
219
220 //=========================================================================
221 // virtual
222 Reference< XContent >
queryContent(sal_uInt32 _nIndex)223 DataSupplier::queryContent( sal_uInt32 _nIndex )
224 {
225 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
226
227 if ( (size_t)_nIndex < m_pImpl->m_aResults.size() )
228 {
229 Reference< XContent > xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get();
230 if ( xContent.is() )
231 {
232 // Already cached.
233 return xContent;
234 }
235 }
236
237 Reference< XContentIdentifier > xId = queryContentIdentifier( _nIndex );
238 if ( xId.is() )
239 {
240 try
241 {
242 Reference< XContent > xContent;
243 ::rtl::OUString sName = xId->getContentIdentifier();
244 sal_Int32 nIndex = sName.lastIndexOf('/') + 1;
245 sName = sName.getToken(0,'/',nIndex);
246
247 m_pImpl->m_aResults[ _nIndex ]->xContent = m_pImpl->m_xContent->getContent(sName);
248
249 xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get();
250 return xContent;
251
252 }
253 catch ( IllegalIdentifierException& )
254 {
255 }
256 }
257 return Reference< XContent >();
258 }
259
260 //=========================================================================
261 // virtual
getResult(sal_uInt32 nIndex)262 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
263 {
264 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
265
266 if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
267 {
268 // Result already present.
269 return sal_True;
270 }
271
272 // Result not (yet) present.
273
274 if ( m_pImpl->m_bCountFinal )
275 return sal_False;
276
277 // Try to obtain result...
278
279 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
280 sal_Bool bFound = sal_False;
281 sal_uInt32 nPos = nOldCount;
282
283 // @@@ Obtain data and put it into result list...
284 Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames();
285 if ( nIndex < sal::static_int_cast< sal_uInt32 >( aSeq.getLength() ) )
286 {
287 const ::rtl::OUString* pIter = aSeq.getConstArray();
288 const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
289 for(pIter = pIter + nPos;pIter != pEnd;++pIter,++nPos)
290 {
291 m_pImpl->m_aResults.push_back(
292 new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) );
293
294 if ( nPos == nIndex )
295 {
296 // Result obtained.
297 bFound = sal_True;
298 break;
299 }
300 }
301 }
302
303 if ( !bFound )
304 m_pImpl->m_bCountFinal = sal_True;
305
306 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
307 if ( xResultSet.is() )
308 {
309 // Callbacks follow!
310 aGuard.clear();
311
312 if ( (size_t)nOldCount < m_pImpl->m_aResults.size() )
313 xResultSet->rowCountChanged(
314 nOldCount, m_pImpl->m_aResults.size() );
315
316 if ( m_pImpl->m_bCountFinal )
317 xResultSet->rowCountFinal();
318 }
319
320 return bFound;
321 }
322
323 //=========================================================================
324 // virtual
totalCount()325 sal_uInt32 DataSupplier::totalCount()
326 {
327 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
328
329 if ( m_pImpl->m_bCountFinal )
330 return m_pImpl->m_aResults.size();
331
332 sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
333
334 // @@@ Obtain data and put it into result list...
335 Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames();
336 const ::rtl::OUString* pIter = aSeq.getConstArray();
337 const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
338 for(;pIter != pEnd;++pIter)
339 m_pImpl->m_aResults.push_back(
340 new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) );
341
342 m_pImpl->m_bCountFinal = sal_True;
343
344 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
345 if ( xResultSet.is() )
346 {
347 // Callbacks follow!
348 aGuard.clear();
349
350 if ( (size_t)nOldCount < m_pImpl->m_aResults.size() )
351 xResultSet->rowCountChanged(
352 nOldCount, m_pImpl->m_aResults.size() );
353
354 xResultSet->rowCountFinal();
355 }
356
357 return m_pImpl->m_aResults.size();
358 }
359
360 //=========================================================================
361 // virtual
currentCount()362 sal_uInt32 DataSupplier::currentCount()
363 {
364 return m_pImpl->m_aResults.size();
365 }
366
367 //=========================================================================
368 // virtual
isCountFinal()369 sal_Bool DataSupplier::isCountFinal()
370 {
371 return m_pImpl->m_bCountFinal;
372 }
373
374 //=========================================================================
375 // virtual
376 Reference< XRow >
queryPropertyValues(sal_uInt32 nIndex)377 DataSupplier::queryPropertyValues( sal_uInt32 nIndex )
378 {
379 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
380
381 if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
382 {
383 Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
384 if ( xRow.is() )
385 {
386 // Already cached.
387 return xRow;
388 }
389 }
390
391 if ( getResult( nIndex ) )
392 {
393 if ( !m_pImpl->m_aResults[ nIndex ]->xContent.is() )
394 queryContent(nIndex);
395
396 Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xContent->getPropertyValues(getResultSet()->getProperties());
397 m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
398 return xRow;
399 }
400
401 return Reference< XRow >();
402 }
403
404 //=========================================================================
405 // virtual
releasePropertyValues(sal_uInt32 nIndex)406 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
407 {
408 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
409
410 if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
411 m_pImpl->m_aResults[ nIndex ]->xRow = Reference< XRow >();
412 }
413
414 //=========================================================================
415 // virtual
close()416 void DataSupplier::close()
417 {
418 }
419
420 //=========================================================================
421 // virtual
validate()422 void DataSupplier::validate()
423 throw( ResultSetException )
424 {
425 }
426
427