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