xref: /trunk/main/dbaccess/source/core/dataaccess/myucp_datasupplier.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dbaccess.hxx"
30 
31 /**************************************************************************
32                                 TODO
33  **************************************************************************
34 
35  *************************************************************************/
36 
37 #include <vector>
38 
39 #ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX
40 #include <ucbhelper/contentidentifier.hxx>
41 #endif
42 #ifndef _UCBHELPER_PROVIDERHELPER_HXX
43 #include <ucbhelper/providerhelper.hxx>
44 #endif
45 
46 #ifndef DBA_DATASUPPLIER_HXX
47 #include "myucp_datasupplier.hxx"
48 #endif
49 #ifndef DBA_CONTENTHELPER_HXX
50 #include "ContentHelper.hxx"
51 #endif
52 #ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMEACCESS_HPP_
53 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
54 #endif
55 #ifndef _TOOLS_DEBUG_HXX
56 #include <tools/debug.hxx>
57 #endif
58 
59 using namespace ::com::sun::star::uno;
60 using namespace ::com::sun::star::ucb;
61 using namespace ::com::sun::star::beans;
62 using namespace ::com::sun::star::lang;
63 using namespace ::com::sun::star::sdbc;
64 using namespace ::com::sun::star::io;
65 using namespace ::com::sun::star::container;
66 
67 // @@@ Adjust namespace name.
68 using namespace dbaccess;
69 
70 // @@@ Adjust namespace name.
71 namespace dbaccess
72 {
73 
74 //=========================================================================
75 //
76 // struct ResultListEntry.
77 //
78 //=========================================================================
79 
80 struct ResultListEntry
81 {
82     rtl::OUString                       aId;
83     Reference< XContentIdentifier >     xId;
84     ::rtl::Reference< OContentHelper >  xContent;
85     Reference< XRow >                   xRow;
86     const ContentProperties&            rData;
87 
88     ResultListEntry( const ContentProperties& rEntry ) : rData( rEntry ) {}
89 };
90 
91 //=========================================================================
92 //
93 // ResultList.
94 //
95 //=========================================================================
96 
97 typedef std::vector< ResultListEntry* > ResultList;
98 
99 //=========================================================================
100 //
101 // struct DataSupplier_Impl.
102 //
103 //=========================================================================
104 
105 struct DataSupplier_Impl
106 {
107     osl::Mutex                                   m_aMutex;
108     ResultList                                   m_aResults;
109     rtl::Reference< ODocumentContainer >             m_xContent;
110     Reference< XMultiServiceFactory >            m_xSMgr;
111     sal_Int32                                    m_nOpenMode;
112     sal_Bool                                     m_bCountFinal;
113 
114     DataSupplier_Impl( const Reference< XMultiServiceFactory >& rxSMgr,
115                         const rtl::Reference< ODocumentContainer >& rContent,
116                        sal_Int32 nOpenMode )
117     : m_xContent(rContent)
118     , m_xSMgr( rxSMgr )
119     , m_nOpenMode( nOpenMode )
120     , m_bCountFinal( sal_False ) {}
121     ~DataSupplier_Impl();
122 };
123 
124 //=========================================================================
125 DataSupplier_Impl::~DataSupplier_Impl()
126 {
127     ResultList::const_iterator it  = m_aResults.begin();
128     ResultList::const_iterator end = m_aResults.end();
129 
130     while ( it != end )
131     {
132         delete (*it);
133         it++;
134     }
135 }
136 
137 }
138 
139 //=========================================================================
140 //=========================================================================
141 //
142 // DataSupplier Implementation.
143 //
144 //=========================================================================
145 //=========================================================================
146 DBG_NAME(DataSupplier)
147 
148 DataSupplier::DataSupplier( const Reference< XMultiServiceFactory >& rxSMgr,
149                            const rtl::Reference< ODocumentContainer >& rContent,
150                             sal_Int32 nOpenMode )
151 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent,nOpenMode ) )
152 {
153     DBG_CTOR(DataSupplier,NULL);
154 
155 }
156 
157 //=========================================================================
158 // virtual
159 DataSupplier::~DataSupplier()
160 {
161 
162     DBG_DTOR(DataSupplier,NULL);
163 }
164 
165 //=========================================================================
166 // virtual
167 rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
168 {
169     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
170 
171     if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
172     {
173         rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
174         if ( aId.getLength() )
175         {
176             // Already cached.
177             return aId;
178         }
179     }
180 
181     if ( getResult( nIndex ) )
182     {
183         rtl::OUString aId
184             = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
185 
186         if ( aId.getLength() )
187             aId += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
188 
189         aId += m_pImpl->m_aResults[ nIndex ]->rData.aTitle;
190 
191         m_pImpl->m_aResults[ nIndex ]->aId = aId;
192         return aId;
193     }
194     return rtl::OUString();
195 }
196 
197 //=========================================================================
198 // virtual
199 Reference< XContentIdentifier >
200 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
201 {
202     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
203 
204     if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
205     {
206         Reference< XContentIdentifier > xId = m_pImpl->m_aResults[ nIndex ]->xId;
207         if ( xId.is() )
208         {
209             // Already cached.
210             return xId;
211         }
212     }
213 
214     rtl::OUString aId = queryContentIdentifierString( nIndex );
215     if ( aId.getLength() )
216     {
217         Reference< XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( aId );
218         m_pImpl->m_aResults[ nIndex ]->xId = xId;
219         return xId;
220     }
221     return Reference< XContentIdentifier >();
222 }
223 
224 //=========================================================================
225 // virtual
226 Reference< XContent >
227 DataSupplier::queryContent( sal_uInt32 _nIndex )
228 {
229     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
230 
231     if ( (size_t)_nIndex < m_pImpl->m_aResults.size() )
232     {
233         Reference< XContent > xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get();
234         if ( xContent.is() )
235         {
236             // Already cached.
237             return xContent;
238         }
239     }
240 
241     Reference< XContentIdentifier > xId = queryContentIdentifier( _nIndex );
242     if ( xId.is() )
243     {
244         try
245         {
246             Reference< XContent > xContent;
247             ::rtl::OUString sName = xId->getContentIdentifier();
248             sal_Int32 nIndex = sName.lastIndexOf('/') + 1;
249             sName = sName.getToken(0,'/',nIndex);
250 
251             m_pImpl->m_aResults[ _nIndex ]->xContent = m_pImpl->m_xContent->getContent(sName);
252 
253             xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get();
254             return xContent;
255 
256         }
257         catch ( IllegalIdentifierException& )
258         {
259         }
260     }
261     return Reference< XContent >();
262 }
263 
264 //=========================================================================
265 // virtual
266 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
267 {
268     osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
269 
270     if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
271     {
272         // Result already present.
273         return sal_True;
274     }
275 
276     // Result not (yet) present.
277 
278     if ( m_pImpl->m_bCountFinal )
279         return sal_False;
280 
281     // Try to obtain result...
282 
283     sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
284     sal_Bool bFound = sal_False;
285     sal_uInt32 nPos = nOldCount;
286 
287     // @@@ Obtain data and put it into result list...
288     Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames();
289     if ( nIndex < sal::static_int_cast< sal_uInt32 >( aSeq.getLength() ) )
290     {
291         const ::rtl::OUString* pIter = aSeq.getConstArray();
292         const ::rtl::OUString* pEnd   = pIter + aSeq.getLength();
293         for(pIter = pIter + nPos;pIter != pEnd;++pIter,++nPos)
294         {
295             m_pImpl->m_aResults.push_back(
296                             new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) );
297 
298             if ( nPos == nIndex )
299             {
300                 // Result obtained.
301                 bFound = sal_True;
302                 break;
303             }
304         }
305     }
306 
307     if ( !bFound )
308         m_pImpl->m_bCountFinal = sal_True;
309 
310     rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
311     if ( xResultSet.is() )
312     {
313         // Callbacks follow!
314         aGuard.clear();
315 
316         if ( (size_t)nOldCount < m_pImpl->m_aResults.size() )
317             xResultSet->rowCountChanged(
318                                     nOldCount, m_pImpl->m_aResults.size() );
319 
320         if ( m_pImpl->m_bCountFinal )
321             xResultSet->rowCountFinal();
322     }
323 
324     return bFound;
325 }
326 
327 //=========================================================================
328 // virtual
329 sal_uInt32 DataSupplier::totalCount()
330 {
331     osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
332 
333     if ( m_pImpl->m_bCountFinal )
334         return m_pImpl->m_aResults.size();
335 
336     sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
337 
338     // @@@ Obtain data and put it into result list...
339     Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames();
340     const ::rtl::OUString* pIter = aSeq.getConstArray();
341     const ::rtl::OUString* pEnd   = pIter + aSeq.getLength();
342     for(;pIter != pEnd;++pIter)
343         m_pImpl->m_aResults.push_back(
344                         new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) );
345 
346     m_pImpl->m_bCountFinal = sal_True;
347 
348     rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get();
349     if ( xResultSet.is() )
350     {
351         // Callbacks follow!
352         aGuard.clear();
353 
354         if ( (size_t)nOldCount < m_pImpl->m_aResults.size() )
355             xResultSet->rowCountChanged(
356                                     nOldCount, m_pImpl->m_aResults.size() );
357 
358         xResultSet->rowCountFinal();
359     }
360 
361     return m_pImpl->m_aResults.size();
362 }
363 
364 //=========================================================================
365 // virtual
366 sal_uInt32 DataSupplier::currentCount()
367 {
368     return m_pImpl->m_aResults.size();
369 }
370 
371 //=========================================================================
372 // virtual
373 sal_Bool DataSupplier::isCountFinal()
374 {
375     return m_pImpl->m_bCountFinal;
376 }
377 
378 //=========================================================================
379 // virtual
380 Reference< XRow >
381 DataSupplier::queryPropertyValues( sal_uInt32 nIndex  )
382 {
383     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
384 
385     if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
386     {
387         Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
388         if ( xRow.is() )
389         {
390             // Already cached.
391             return xRow;
392         }
393     }
394 
395     if ( getResult( nIndex ) )
396     {
397         if ( !m_pImpl->m_aResults[ nIndex ]->xContent.is() )
398             queryContent(nIndex);
399 
400         Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xContent->getPropertyValues(getResultSet()->getProperties());
401         m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
402         return xRow;
403     }
404 
405     return Reference< XRow >();
406 }
407 
408 //=========================================================================
409 // virtual
410 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
411 {
412     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
413 
414     if ( (size_t)nIndex < m_pImpl->m_aResults.size() )
415         m_pImpl->m_aResults[ nIndex ]->xRow = Reference< XRow >();
416 }
417 
418 //=========================================================================
419 // virtual
420 void DataSupplier::close()
421 {
422 }
423 
424 //=========================================================================
425 // virtual
426 void DataSupplier::validate()
427     throw( ResultSetException )
428 {
429 }
430 
431