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 67 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 96 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 //========================================================================= 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 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 137 DataSupplier::~DataSupplier() 138 { 139 delete m_pImpl; 140 } 141 142 //========================================================================= 143 // virtual 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 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 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 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 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 387 sal_uInt32 DataSupplier::currentCount() 388 { 389 return m_pImpl->m_aResults.size(); 390 } 391 392 //========================================================================= 393 // virtual 394 sal_Bool DataSupplier::isCountFinal() 395 { 396 return m_pImpl->m_bCountFinal; 397 } 398 399 //========================================================================= 400 // virtual 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 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 442 void DataSupplier::close() 443 { 444 } 445 446 //========================================================================= 447 // virtual 448 void DataSupplier::validate() 449 throw( ResultSetException ) 450 { 451 } 452