xref: /trunk/main/ucb/source/ucp/odma/odma_datasupplier.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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_ucb.hxx"
30 
31 /**************************************************************************
32                                 TODO
33  **************************************************************************
34 
35  *************************************************************************/
36 
37 #include <vector>
38 #include <ucbhelper/contentidentifier.hxx>
39 #include <ucbhelper/providerhelper.hxx>
40 #include "odma_datasupplier.hxx"
41 #include "odma_content.hxx"
42 #include "odma_contentprops.hxx"
43 #include "odma_provider.hxx"
44 #include "odma_lib.hxx"
45 
46 using namespace com::sun::star::beans;
47 using namespace com::sun::star::lang;
48 using namespace com::sun::star::ucb;
49 using namespace com::sun::star::uno;
50 using namespace com::sun::star::sdbc;
51 
52 using namespace odma;
53 
54 namespace odma
55 {
56 
57 //=========================================================================
58 //
59 // struct ResultListEntry.
60 //
61 //=========================================================================
62 
63 struct ResultListEntry
64 {
65     ::rtl::OUString                     aId;
66     Reference< XContentIdentifier >     xId;
67     Reference< XContent >               xContent;
68     Reference< XRow >                   xRow;
69     ::rtl::Reference<ContentProperties> rData;
70 
71     ResultListEntry( const ::rtl::Reference<ContentProperties>& rEntry ) : rData( rEntry ) {}
72 };
73 
74 //=========================================================================
75 //
76 // ResultList.
77 //
78 //=========================================================================
79 
80 typedef std::vector< ResultListEntry* > ResultList;
81 
82 //=========================================================================
83 //
84 // struct DataSupplier_Impl.
85 //
86 //=========================================================================
87 
88 struct DataSupplier_Impl
89 {
90     osl::Mutex                        m_aMutex;
91     ResultList                        m_aResults;
92     rtl::Reference< Content >         m_xContent;
93     Reference< XMultiServiceFactory > m_xSMgr;
94 // @@@ The data source and an iterator for it
95 //  Entry                             m_aFolder;
96 //  Entry::iterator                   m_aIterator;
97     sal_Int32                         m_nOpenMode;
98     sal_Bool                          m_bCountFinal;
99 
100     DataSupplier_Impl( const Reference< XMultiServiceFactory >& rxSMgr,
101                        const rtl::Reference< Content >& rContent,
102                        sal_Int32 nOpenMode )
103     : m_xContent( rContent ), m_xSMgr( rxSMgr ),
104 //    m_aFolder( rxSMgr, rContent->getIdentifier()->getContentIdentifier() ),
105       m_nOpenMode( nOpenMode ), m_bCountFinal( sal_False ) {}
106     ~DataSupplier_Impl();
107 };
108 
109 //=========================================================================
110 DataSupplier_Impl::~DataSupplier_Impl()
111 {
112     ResultList::const_iterator it  = m_aResults.begin();
113     ResultList::const_iterator end = m_aResults.end();
114 
115     while ( it != end )
116     {
117         delete (*it);
118         it++;
119     }
120 }
121 
122 }
123 
124 //=========================================================================
125 //=========================================================================
126 //
127 // DataSupplier Implementation.
128 //
129 //=========================================================================
130 //=========================================================================
131 
132 DataSupplier::DataSupplier( const Reference<XMultiServiceFactory >& rxSMgr,
133                            const rtl::Reference< ::odma::Content >& rContent,
134                             sal_Int32 nOpenMode )
135 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent, nOpenMode ) )
136 {
137 }
138 
139 //=========================================================================
140 // virtual
141 DataSupplier::~DataSupplier()
142 {
143     delete m_pImpl;
144 }
145 
146 //=========================================================================
147 // virtual
148 ::rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
149 {
150     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
151 
152     if ( nIndex < m_pImpl->m_aResults.size() )
153     {
154         ::rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId;
155         if ( aId.getLength() )
156         {
157             // Already cached.
158             return aId;
159         }
160     }
161 
162     if ( getResult( nIndex ) )
163     {
164         ::rtl::OUString aId
165             = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier();
166 
167         aId += m_pImpl->m_aResults[ nIndex ]->rData->m_sTitle;
168 
169         m_pImpl->m_aResults[ nIndex ]->aId = aId;
170         return aId;
171     }
172     return ::rtl::OUString();
173 }
174 
175 //=========================================================================
176 // virtual
177 Reference< XContentIdentifier > DataSupplier::queryContentIdentifier(
178                                                         sal_uInt32 nIndex )
179 {
180     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
181 
182     if ( nIndex < m_pImpl->m_aResults.size() )
183     {
184         Reference< XContentIdentifier > xId
185                                 = m_pImpl->m_aResults[ nIndex ]->xId;
186         if ( xId.is() )
187         {
188             // Already cached.
189             return xId;
190         }
191     }
192 
193     ::rtl::OUString aId = queryContentIdentifierString( nIndex );
194     if ( aId.getLength() )
195     {
196         Reference< XContentIdentifier > xId
197             = new ucbhelper::ContentIdentifier( aId );
198         m_pImpl->m_aResults[ nIndex ]->xId = xId;
199         return xId;
200     }
201     return Reference< XContentIdentifier >();
202 }
203 
204 //=========================================================================
205 // virtual
206 Reference< XContent > DataSupplier::queryContent( sal_uInt32 nIndex )
207 {
208     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
209 
210     if ( nIndex < m_pImpl->m_aResults.size() )
211     {
212         Reference< XContent > xContent
213                                 = m_pImpl->m_aResults[ nIndex ]->xContent;
214         if ( xContent.is() )
215         {
216             // Already cached.
217             return xContent;
218         }
219     }
220 
221     Reference< XContentIdentifier > xId = queryContentIdentifier( nIndex );
222     if ( xId.is() )
223     {
224         try
225         {
226             Reference< XContent > xContent
227                 = m_pImpl->m_xContent->getProvider()->queryContent( xId );
228             m_pImpl->m_aResults[ nIndex ]->xContent = xContent;
229             return xContent;
230 
231         }
232         catch ( IllegalIdentifierException& )
233         {
234         }
235     }
236     return Reference< XContent >();
237 }
238 
239 //=========================================================================
240 // virtual
241 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
242 {
243     osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
244 
245     if ( m_pImpl->m_aResults.size() > nIndex )
246     {
247         // Result already present.
248         return sal_True;
249     }
250 
251     // Result not (yet) present.
252 
253     if ( m_pImpl->m_bCountFinal )
254         return sal_False;
255 
256     // Try to obtain result...
257 
258     sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
259     sal_Bool bFound = sal_False;
260 //  sal_uInt32 nPos = nOldCount;
261 
262     // @@@ Obtain data and put it into result list...
263 /*
264     while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
265     {
266         m_pImpl->m_aResults.push_back(
267                         new ResultListEntry( *m_pImpl->m_aIterator ) );
268 
269         if ( nPos == nIndex )
270         {
271             // Result obtained.
272             bFound = sal_True;
273             break;
274         }
275 
276         nPos++;
277     }
278 */
279     // now query for all documents in the DMS
280     OSL_ENSURE(ContentProvider::getHandle(),"No Handle!");
281     sal_Char* pQueryId      = new sal_Char[ODM_QUERYID_MAX];
282     sal_Char* lpszDMSList   = new sal_Char[ODM_DMSID_MAX];
283 
284     ODMSTATUS odm = NODMGetDMS(ODMA_ODMA_REGNAME, lpszDMSList);
285     lpszDMSList[strlen(lpszDMSList)+1] = '\0';
286 
287     ::rtl::OString sQuery("SELECT ODM_DOCID, ODM_NAME");
288 
289     DWORD dwFlags = ODM_SPECIFIC;
290     odm = NODMQueryExecute(ContentProvider::getHandle(), sQuery,dwFlags, lpszDMSList, pQueryId );
291     if(odm != ODM_SUCCESS)
292         return sal_False;
293 
294     sal_uInt16 nCount       = 10;
295     sal_uInt16 nMaxCount    = 10;
296     sal_Char* lpszDocId     = new sal_Char[ODM_DOCID_MAX * nMaxCount];
297     sal_Char* lpszDocName   = new sal_Char[ODM_NAME_MAX * nMaxCount];
298 
299 
300     ::rtl::OUString sContentType(RTL_CONSTASCII_USTRINGPARAM(ODMA_CONTENT_TYPE));
301     sal_uInt32 nCurrentCount = 0;
302     do
303     {
304         if(nCount >= nMaxCount)
305         {
306             nCount = nMaxCount;
307             odm = NODMQueryGetResults(ContentProvider::getHandle(), pQueryId,lpszDocId, lpszDocName, ODM_NAME_MAX, (WORD*)&nCount);
308             nCurrentCount += nCount;
309         }
310         if(odm == ODM_SUCCESS && nIndex < nCurrentCount)
311         {
312             bFound = sal_True;
313             for(sal_uInt16 i = 0; i < nCount; ++i)
314             {
315                 ::rtl::Reference<ContentProperties> rProps = new ContentProperties();
316                 rProps->m_sDocumentId   = ::rtl::OString(&lpszDocId[ODM_DOCID_MAX*i]);
317                 rProps->m_sContentType  = sContentType;
318                 m_pImpl->m_xContent->getContentProvider()->append(rProps);
319                 m_pImpl->m_aResults.push_back( new ResultListEntry(rProps));
320             }
321         }
322     }
323     while(nCount > nMaxCount);
324 
325 
326     // now close the query
327     odm = NODMQueryClose(ContentProvider::getHandle(), pQueryId);
328 
329     delete [] lpszDMSList;
330     delete [] pQueryId;
331     delete [] lpszDocId;
332     delete [] lpszDocName;
333 
334     if ( !bFound )
335         m_pImpl->m_bCountFinal = sal_True;
336 
337     rtl::Reference< ucbhelper::ResultSet > xResultSet = getResultSet();
338     if ( xResultSet.is() )
339     {
340         // Callbacks follow!
341         aGuard.clear();
342 
343         if ( nOldCount < m_pImpl->m_aResults.size() )
344             xResultSet->rowCountChanged(
345                                     nOldCount, m_pImpl->m_aResults.size() );
346 
347         if ( m_pImpl->m_bCountFinal )
348             xResultSet->rowCountFinal();
349     }
350 
351     return bFound;
352 }
353 
354 //=========================================================================
355 // virtual
356 sal_uInt32 DataSupplier::totalCount()
357 {
358     osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
359 
360     if ( m_pImpl->m_bCountFinal )
361         return m_pImpl->m_aResults.size();
362 
363     sal_uInt32 nOldCount = m_pImpl->m_aResults.size();
364 
365     // @@@ Obtain data and put it into result list...
366 /*
367     while ( m_pImpl->m_aFolder.next( m_pImpl->m_aIterator ) )
368         m_pImpl->m_aResults.push_back(
369                         new ResultListEntry( *m_pImpl->m_aIterator ) );
370 */
371     m_pImpl->m_bCountFinal = sal_True;
372 
373     rtl::Reference< ucbhelper::ResultSet > xResultSet = getResultSet();
374     if ( xResultSet.is() )
375     {
376         // Callbacks follow!
377         aGuard.clear();
378 
379         if ( nOldCount < m_pImpl->m_aResults.size() )
380             xResultSet->rowCountChanged(
381                                     nOldCount, m_pImpl->m_aResults.size() );
382 
383         xResultSet->rowCountFinal();
384     }
385 
386     return m_pImpl->m_aResults.size();
387 }
388 
389 //=========================================================================
390 // virtual
391 sal_uInt32 DataSupplier::currentCount()
392 {
393     return m_pImpl->m_aResults.size();
394 }
395 
396 //=========================================================================
397 // virtual
398 sal_Bool DataSupplier::isCountFinal()
399 {
400     return m_pImpl->m_bCountFinal;
401 }
402 
403 //=========================================================================
404 // virtual
405 Reference< XRow > DataSupplier::queryPropertyValues( sal_uInt32 nIndex  )
406 {
407     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
408 
409     if ( nIndex < m_pImpl->m_aResults.size() )
410     {
411         Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow;
412         if ( xRow.is() )
413         {
414             // Already cached.
415             return xRow;
416         }
417     }
418 
419     if ( getResult( nIndex ) )
420     {
421         Reference< XRow > xRow = Content::getPropertyValues(
422                                     m_pImpl->m_xSMgr,
423                                     getResultSet()->getProperties(),
424                                     m_pImpl->m_aResults[ nIndex ]->rData,
425                                     m_pImpl->m_xContent->getProvider(),
426                                     queryContentIdentifierString( nIndex ) );
427         m_pImpl->m_aResults[ nIndex ]->xRow = xRow;
428         return xRow;
429     }
430 
431     return Reference< XRow >();
432 }
433 
434 //=========================================================================
435 // virtual
436 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
437 {
438     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
439 
440     if ( nIndex < m_pImpl->m_aResults.size() )
441         m_pImpl->m_aResults[ nIndex ]->xRow = Reference< XRow >();
442 }
443 
444 //=========================================================================
445 // virtual
446 void DataSupplier::close()
447 {
448 }
449 
450 //=========================================================================
451 // virtual
452 void DataSupplier::validate()
453     throw( ResultSetException )
454 {
455 }
456