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