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