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_dbaccess.hxx" 26 27 /************************************************************************** 28 TODO 29 ************************************************************************** 30 31 *************************************************************************/ 32 33 #include <vector> 34 35 #ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX 36 #include <ucbhelper/contentidentifier.hxx> 37 #endif 38 #ifndef _UCBHELPER_PROVIDERHELPER_HXX 39 #include <ucbhelper/providerhelper.hxx> 40 #endif 41 42 #ifndef DBA_DATASUPPLIER_HXX 43 #include "myucp_datasupplier.hxx" 44 #endif 45 #ifndef DBA_CONTENTHELPER_HXX 46 #include "ContentHelper.hxx" 47 #endif 48 #ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMEACCESS_HPP_ 49 #include <com/sun/star/container/XHierarchicalNameAccess.hpp> 50 #endif 51 #ifndef _TOOLS_DEBUG_HXX 52 #include <tools/debug.hxx> 53 #endif 54 55 using namespace ::com::sun::star::uno; 56 using namespace ::com::sun::star::ucb; 57 using namespace ::com::sun::star::beans; 58 using namespace ::com::sun::star::lang; 59 using namespace ::com::sun::star::sdbc; 60 using namespace ::com::sun::star::io; 61 using namespace ::com::sun::star::container; 62 63 // @@@ Adjust namespace name. 64 using namespace dbaccess; 65 66 // @@@ Adjust namespace name. 67 namespace dbaccess 68 { 69 70 //========================================================================= 71 // 72 // struct ResultListEntry. 73 // 74 //========================================================================= 75 76 struct ResultListEntry 77 { 78 rtl::OUString aId; 79 Reference< XContentIdentifier > xId; 80 ::rtl::Reference< OContentHelper > xContent; 81 Reference< XRow > xRow; 82 const ContentProperties& rData; 83 84 ResultListEntry( const ContentProperties& rEntry ) : rData( rEntry ) {} 85 }; 86 87 //========================================================================= 88 // 89 // ResultList. 90 // 91 //========================================================================= 92 93 typedef std::vector< ResultListEntry* > ResultList; 94 95 //========================================================================= 96 // 97 // struct DataSupplier_Impl. 98 // 99 //========================================================================= 100 101 struct DataSupplier_Impl 102 { 103 osl::Mutex m_aMutex; 104 ResultList m_aResults; 105 rtl::Reference< ODocumentContainer > m_xContent; 106 Reference< XMultiServiceFactory > m_xSMgr; 107 sal_Int32 m_nOpenMode; 108 sal_Bool m_bCountFinal; 109 110 DataSupplier_Impl( const Reference< XMultiServiceFactory >& rxSMgr, 111 const rtl::Reference< ODocumentContainer >& rContent, 112 sal_Int32 nOpenMode ) 113 : m_xContent(rContent) 114 , m_xSMgr( rxSMgr ) 115 , m_nOpenMode( nOpenMode ) 116 , m_bCountFinal( sal_False ) {} 117 ~DataSupplier_Impl(); 118 }; 119 120 //========================================================================= 121 DataSupplier_Impl::~DataSupplier_Impl() 122 { 123 ResultList::const_iterator it = m_aResults.begin(); 124 ResultList::const_iterator end = m_aResults.end(); 125 126 while ( it != end ) 127 { 128 delete (*it); 129 it++; 130 } 131 } 132 133 } 134 135 //========================================================================= 136 //========================================================================= 137 // 138 // DataSupplier Implementation. 139 // 140 //========================================================================= 141 //========================================================================= 142 DBG_NAME(DataSupplier) 143 144 DataSupplier::DataSupplier( const Reference< XMultiServiceFactory >& rxSMgr, 145 const rtl::Reference< ODocumentContainer >& rContent, 146 sal_Int32 nOpenMode ) 147 : m_pImpl( new DataSupplier_Impl( rxSMgr, rContent,nOpenMode ) ) 148 { 149 DBG_CTOR(DataSupplier,NULL); 150 151 } 152 153 //========================================================================= 154 // virtual 155 DataSupplier::~DataSupplier() 156 { 157 158 DBG_DTOR(DataSupplier,NULL); 159 } 160 161 //========================================================================= 162 // virtual 163 rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex ) 164 { 165 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 166 167 if ( (size_t)nIndex < m_pImpl->m_aResults.size() ) 168 { 169 rtl::OUString aId = m_pImpl->m_aResults[ nIndex ]->aId; 170 if ( aId.getLength() ) 171 { 172 // Already cached. 173 return aId; 174 } 175 } 176 177 if ( getResult( nIndex ) ) 178 { 179 rtl::OUString aId 180 = m_pImpl->m_xContent->getIdentifier()->getContentIdentifier(); 181 182 if ( aId.getLength() ) 183 aId += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")); 184 185 aId += m_pImpl->m_aResults[ nIndex ]->rData.aTitle; 186 187 m_pImpl->m_aResults[ nIndex ]->aId = aId; 188 return aId; 189 } 190 return rtl::OUString(); 191 } 192 193 //========================================================================= 194 // virtual 195 Reference< XContentIdentifier > 196 DataSupplier::queryContentIdentifier( sal_uInt32 nIndex ) 197 { 198 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 199 200 if ( (size_t)nIndex < m_pImpl->m_aResults.size() ) 201 { 202 Reference< XContentIdentifier > xId = m_pImpl->m_aResults[ nIndex ]->xId; 203 if ( xId.is() ) 204 { 205 // Already cached. 206 return xId; 207 } 208 } 209 210 rtl::OUString aId = queryContentIdentifierString( nIndex ); 211 if ( aId.getLength() ) 212 { 213 Reference< XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( aId ); 214 m_pImpl->m_aResults[ nIndex ]->xId = xId; 215 return xId; 216 } 217 return Reference< XContentIdentifier >(); 218 } 219 220 //========================================================================= 221 // virtual 222 Reference< XContent > 223 DataSupplier::queryContent( sal_uInt32 _nIndex ) 224 { 225 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 226 227 if ( (size_t)_nIndex < m_pImpl->m_aResults.size() ) 228 { 229 Reference< XContent > xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get(); 230 if ( xContent.is() ) 231 { 232 // Already cached. 233 return xContent; 234 } 235 } 236 237 Reference< XContentIdentifier > xId = queryContentIdentifier( _nIndex ); 238 if ( xId.is() ) 239 { 240 try 241 { 242 Reference< XContent > xContent; 243 ::rtl::OUString sName = xId->getContentIdentifier(); 244 sal_Int32 nIndex = sName.lastIndexOf('/') + 1; 245 sName = sName.getToken(0,'/',nIndex); 246 247 m_pImpl->m_aResults[ _nIndex ]->xContent = m_pImpl->m_xContent->getContent(sName); 248 249 xContent = m_pImpl->m_aResults[ _nIndex ]->xContent.get(); 250 return xContent; 251 252 } 253 catch ( IllegalIdentifierException& ) 254 { 255 } 256 } 257 return Reference< XContent >(); 258 } 259 260 //========================================================================= 261 // virtual 262 sal_Bool DataSupplier::getResult( sal_uInt32 nIndex ) 263 { 264 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 265 266 if ( (size_t)nIndex < m_pImpl->m_aResults.size() ) 267 { 268 // Result already present. 269 return sal_True; 270 } 271 272 // Result not (yet) present. 273 274 if ( m_pImpl->m_bCountFinal ) 275 return sal_False; 276 277 // Try to obtain result... 278 279 sal_uInt32 nOldCount = m_pImpl->m_aResults.size(); 280 sal_Bool bFound = sal_False; 281 sal_uInt32 nPos = nOldCount; 282 283 // @@@ Obtain data and put it into result list... 284 Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames(); 285 if ( nIndex < sal::static_int_cast< sal_uInt32 >( aSeq.getLength() ) ) 286 { 287 const ::rtl::OUString* pIter = aSeq.getConstArray(); 288 const ::rtl::OUString* pEnd = pIter + aSeq.getLength(); 289 for(pIter = pIter + nPos;pIter != pEnd;++pIter,++nPos) 290 { 291 m_pImpl->m_aResults.push_back( 292 new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) ); 293 294 if ( nPos == nIndex ) 295 { 296 // Result obtained. 297 bFound = sal_True; 298 break; 299 } 300 } 301 } 302 303 if ( !bFound ) 304 m_pImpl->m_bCountFinal = sal_True; 305 306 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get(); 307 if ( xResultSet.is() ) 308 { 309 // Callbacks follow! 310 aGuard.clear(); 311 312 if ( (size_t)nOldCount < m_pImpl->m_aResults.size() ) 313 xResultSet->rowCountChanged( 314 nOldCount, m_pImpl->m_aResults.size() ); 315 316 if ( m_pImpl->m_bCountFinal ) 317 xResultSet->rowCountFinal(); 318 } 319 320 return bFound; 321 } 322 323 //========================================================================= 324 // virtual 325 sal_uInt32 DataSupplier::totalCount() 326 { 327 osl::ClearableGuard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 328 329 if ( m_pImpl->m_bCountFinal ) 330 return m_pImpl->m_aResults.size(); 331 332 sal_uInt32 nOldCount = m_pImpl->m_aResults.size(); 333 334 // @@@ Obtain data and put it into result list... 335 Sequence< ::rtl::OUString> aSeq = m_pImpl->m_xContent->getElementNames(); 336 const ::rtl::OUString* pIter = aSeq.getConstArray(); 337 const ::rtl::OUString* pEnd = pIter + aSeq.getLength(); 338 for(;pIter != pEnd;++pIter) 339 m_pImpl->m_aResults.push_back( 340 new ResultListEntry( m_pImpl->m_xContent->getContent(*pIter)->getContentProperties() ) ); 341 342 m_pImpl->m_bCountFinal = sal_True; 343 344 rtl::Reference< ::ucbhelper::ResultSet > xResultSet = getResultSet().get(); 345 if ( xResultSet.is() ) 346 { 347 // Callbacks follow! 348 aGuard.clear(); 349 350 if ( (size_t)nOldCount < m_pImpl->m_aResults.size() ) 351 xResultSet->rowCountChanged( 352 nOldCount, m_pImpl->m_aResults.size() ); 353 354 xResultSet->rowCountFinal(); 355 } 356 357 return m_pImpl->m_aResults.size(); 358 } 359 360 //========================================================================= 361 // virtual 362 sal_uInt32 DataSupplier::currentCount() 363 { 364 return m_pImpl->m_aResults.size(); 365 } 366 367 //========================================================================= 368 // virtual 369 sal_Bool DataSupplier::isCountFinal() 370 { 371 return m_pImpl->m_bCountFinal; 372 } 373 374 //========================================================================= 375 // virtual 376 Reference< XRow > 377 DataSupplier::queryPropertyValues( sal_uInt32 nIndex ) 378 { 379 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 380 381 if ( (size_t)nIndex < m_pImpl->m_aResults.size() ) 382 { 383 Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xRow; 384 if ( xRow.is() ) 385 { 386 // Already cached. 387 return xRow; 388 } 389 } 390 391 if ( getResult( nIndex ) ) 392 { 393 if ( !m_pImpl->m_aResults[ nIndex ]->xContent.is() ) 394 queryContent(nIndex); 395 396 Reference< XRow > xRow = m_pImpl->m_aResults[ nIndex ]->xContent->getPropertyValues(getResultSet()->getProperties()); 397 m_pImpl->m_aResults[ nIndex ]->xRow = xRow; 398 return xRow; 399 } 400 401 return Reference< XRow >(); 402 } 403 404 //========================================================================= 405 // virtual 406 void DataSupplier::releasePropertyValues( sal_uInt32 nIndex ) 407 { 408 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 409 410 if ( (size_t)nIndex < m_pImpl->m_aResults.size() ) 411 m_pImpl->m_aResults[ nIndex ]->xRow = Reference< XRow >(); 412 } 413 414 //========================================================================= 415 // virtual 416 void DataSupplier::close() 417 { 418 } 419 420 //========================================================================= 421 // virtual 422 void DataSupplier::validate() 423 throw( ResultSetException ) 424 { 425 } 426 427