1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2010 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 ************************************************************************/ 26 27 #include "precompiled_ucb.hxx" 28 29 #include "ucpext_datasupplier.hxx" 30 #include "ucpext_content.hxx" 31 #include "ucpext_provider.hxx" 32 33 /** === begin UNO includes === **/ 34 #include <com/sun/star/deployment/XPackageInformationProvider.hpp> 35 /** === end UNO includes === **/ 36 37 #include <ucbhelper/contentidentifier.hxx> 38 #include <comphelper/componentcontext.hxx> 39 #include <ucbhelper/providerhelper.hxx> 40 #include <ucbhelper/content.hxx> 41 #include <ucbhelper/propertyvalueset.hxx> 42 #include <tools/diagnose_ex.h> 43 #include <rtl/ustrbuf.hxx> 44 45 #include <vector> 46 #include <boost/shared_ptr.hpp> 47 48 //...................................................................................................................... 49 namespace ucb { namespace ucp { namespace ext 50 { 51 //...................................................................................................................... 52 53 /** === begin UNO using === **/ 54 using ::com::sun::star::uno::Reference; 55 using ::com::sun::star::uno::XInterface; 56 using ::com::sun::star::uno::UNO_QUERY; 57 using ::com::sun::star::uno::UNO_QUERY_THROW; 58 using ::com::sun::star::uno::UNO_SET_THROW; 59 using ::com::sun::star::uno::Exception; 60 using ::com::sun::star::uno::RuntimeException; 61 using ::com::sun::star::uno::Any; 62 using ::com::sun::star::uno::makeAny; 63 using ::com::sun::star::uno::Sequence; 64 using ::com::sun::star::uno::Type; 65 using ::com::sun::star::ucb::XContent; 66 using ::com::sun::star::ucb::XContentIdentifier; 67 using ::com::sun::star::sdbc::XRow; 68 using ::com::sun::star::lang::XMultiServiceFactory; 69 using ::com::sun::star::ucb::IllegalIdentifierException; 70 using ::com::sun::star::ucb::ResultSetException; 71 using ::com::sun::star::deployment::XPackageInformationProvider; 72 using ::com::sun::star::beans::Property; 73 using ::com::sun::star::sdbc::XResultSet; 74 using ::com::sun::star::sdbc::XRow; 75 using ::com::sun::star::ucb::XCommandEnvironment; 76 /** === end UNO using === **/ 77 //================================================================================================================== 78 //= ResultListEntry 79 //================================================================================================================== 80 struct ResultListEntry 81 { 82 ::rtl::OUString sId; 83 Reference< XContentIdentifier > xId; 84 ::rtl::Reference< Content > pContent; 85 Reference< XRow > xRow; 86 }; 87 88 typedef ::std::vector< ResultListEntry > ResultList; 89 90 //================================================================================================================== 91 //= DataSupplier_Impl 92 //================================================================================================================== 93 struct DataSupplier_Impl 94 { 95 ::osl::Mutex m_aMutex; 96 ResultList m_aResults; 97 ::rtl::Reference< Content > m_xContent; 98 Reference< XMultiServiceFactory > m_xSMgr; 99 sal_Int32 m_nOpenMode; 100 101 DataSupplier_Impl( const Reference< XMultiServiceFactory >& i_rORB, const ::rtl::Reference< Content >& i_rContent, 102 const sal_Int32 i_nOpenMode ) 103 :m_xContent( i_rContent ) 104 ,m_xSMgr( i_rORB ) 105 ,m_nOpenMode( i_nOpenMode ) 106 { 107 } 108 ~DataSupplier_Impl(); 109 }; 110 111 //------------------------------------------------------------------------------------------------------------------ 112 DataSupplier_Impl::~DataSupplier_Impl() 113 { 114 } 115 116 //================================================================================================================== 117 //= helper 118 //================================================================================================================== 119 namespace 120 { 121 ::rtl::OUString lcl_compose( const ::rtl::OUString& i_rBaseURL, const ::rtl::OUString& i_rRelativeURL ) 122 { 123 ENSURE_OR_RETURN( i_rBaseURL.getLength(), "illegal base URL", i_rRelativeURL ); 124 125 ::rtl::OUStringBuffer aComposer( i_rBaseURL ); 126 if ( i_rBaseURL.getStr()[ i_rBaseURL.getLength() - 1 ] != '/' ) 127 aComposer.append( sal_Unicode( '/' ) ); 128 aComposer.append( i_rRelativeURL ); 129 return aComposer.makeStringAndClear(); 130 } 131 } 132 133 134 //================================================================================================================== 135 //= DataSupplier 136 //================================================================================================================== 137 //------------------------------------------------------------------------------------------------------------------ 138 DataSupplier::DataSupplier( const Reference< XMultiServiceFactory >& i_rORB, 139 const ::rtl::Reference< Content >& i_rContent, 140 const sal_Int32 i_nOpenMode ) 141 :m_pImpl( new DataSupplier_Impl( i_rORB, i_rContent, i_nOpenMode ) ) 142 { 143 } 144 145 //------------------------------------------------------------------------------------------------------------------ 146 void DataSupplier::fetchData() 147 { 148 try 149 { 150 const ::comphelper::ComponentContext aContext( m_pImpl->m_xSMgr ); 151 const Reference< XPackageInformationProvider > xPackageInfo( 152 aContext.getSingleton( "com.sun.star.deployment.PackageInformationProvider" ), UNO_QUERY_THROW ); 153 154 const ::rtl::OUString sContentIdentifier( m_pImpl->m_xContent->getIdentifier()->getContentIdentifier() ); 155 156 switch ( m_pImpl->m_xContent->getExtensionContentType() ) 157 { 158 case E_ROOT: 159 { 160 Sequence< Sequence< ::rtl::OUString > > aExtensionInfo( xPackageInfo->getExtensionList() ); 161 for ( const Sequence< ::rtl::OUString >* pExtInfo = aExtensionInfo.getConstArray(); 162 pExtInfo != aExtensionInfo.getConstArray() + aExtensionInfo.getLength(); 163 ++pExtInfo 164 ) 165 { 166 ENSURE_OR_CONTINUE( pExtInfo->getLength() > 0, "illegal extension info" ); 167 168 const ::rtl::OUString& rLocalId = (*pExtInfo)[0]; 169 ResultListEntry aEntry; 170 aEntry.sId = ContentProvider::getRootURL() + Content::encodeIdentifier( rLocalId ) + ::rtl::OUString( sal_Unicode( '/' ) ); 171 m_pImpl->m_aResults.push_back( aEntry ); 172 } 173 } 174 break; 175 case E_EXTENSION_ROOT: 176 case E_EXTENSION_CONTENT: 177 { 178 const ::rtl::OUString sPackageLocation( m_pImpl->m_xContent->getPhysicalURL() ); 179 ::ucbhelper::Content aWrappedContent( sPackageLocation, getResultSet()->getEnvironment() ); 180 181 // obtain the properties which our result set is set up for from the wrapped content 182 Sequence< ::rtl::OUString > aPropertyNames(1); 183 aPropertyNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ); 184 185 const Reference< XResultSet > xFolderContent( aWrappedContent.createCursor( aPropertyNames ), UNO_SET_THROW ); 186 const Reference< XRow > xContentRow( xFolderContent, UNO_QUERY_THROW ); 187 while ( xFolderContent->next() ) 188 { 189 ResultListEntry aEntry; 190 aEntry.sId = lcl_compose( sContentIdentifier, xContentRow->getString( 1 ) ); 191 m_pImpl->m_aResults.push_back( aEntry ); 192 } 193 } 194 break; 195 default: 196 OSL_ENSURE( false, "DataSupplier::fetchData: unimplemented content type!" ); 197 break; 198 } 199 } 200 catch( const Exception& ) 201 { 202 DBG_UNHANDLED_EXCEPTION(); 203 } 204 } 205 206 //------------------------------------------------------------------------------------------------------------------ 207 DataSupplier::~DataSupplier() 208 { 209 } 210 211 //------------------------------------------------------------------------------------------------------------------ 212 ::rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 i_nIndex ) 213 { 214 ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); 215 216 if ( i_nIndex < m_pImpl->m_aResults.size() ) 217 { 218 const ::rtl::OUString sId = m_pImpl->m_aResults[ i_nIndex ].sId; 219 if ( sId.getLength() ) 220 return sId; 221 } 222 223 OSL_ENSURE( false, "DataSupplier::queryContentIdentifierString: illegal index, or illegal result entry id!" ); 224 return ::rtl::OUString(); 225 } 226 227 //------------------------------------------------------------------------------------------------------------------ 228 Reference< XContentIdentifier > DataSupplier::queryContentIdentifier( sal_uInt32 i_nIndex ) 229 { 230 ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); 231 232 if ( i_nIndex < m_pImpl->m_aResults.size() ) 233 { 234 Reference< XContentIdentifier > xId( m_pImpl->m_aResults[ i_nIndex ].xId ); 235 if ( xId.is() ) 236 return xId; 237 } 238 239 ::rtl::OUString sId = queryContentIdentifierString( i_nIndex ); 240 if ( sId.getLength() ) 241 { 242 Reference< XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( sId ); 243 m_pImpl->m_aResults[ i_nIndex ].xId = xId; 244 return xId; 245 } 246 247 return Reference< XContentIdentifier >(); 248 } 249 250 //------------------------------------------------------------------------------------------------------------------ 251 Reference< XContent > DataSupplier::queryContent( sal_uInt32 i_nIndex ) 252 { 253 ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); 254 ENSURE_OR_RETURN( i_nIndex < m_pImpl->m_aResults.size(), "illegal index!", NULL ); 255 256 257 ::rtl::Reference< Content > pContent( m_pImpl->m_aResults[ i_nIndex ].pContent ); 258 if ( pContent.is() ) 259 return pContent.get(); 260 261 Reference< XContentIdentifier > xId( queryContentIdentifier( i_nIndex ) ); 262 if ( xId.is() ) 263 { 264 try 265 { 266 Reference< XContent > xContent( m_pImpl->m_xContent->getProvider()->queryContent( xId ) ); 267 pContent.set( dynamic_cast< Content* >( xContent.get() ) ); 268 OSL_ENSURE( pContent.is() || !xContent.is(), "DataSupplier::queryContent: invalid content implementation!" ); 269 m_pImpl->m_aResults[ i_nIndex ].pContent = pContent; 270 return pContent.get(); 271 272 } 273 catch ( const IllegalIdentifierException& ) 274 { 275 DBG_UNHANDLED_EXCEPTION(); 276 } 277 } 278 279 return Reference< XContent >(); 280 } 281 282 //------------------------------------------------------------------------------------------------------------------ 283 sal_Bool DataSupplier::getResult( sal_uInt32 i_nIndex ) 284 { 285 ::osl::ClearableGuard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); 286 287 if ( m_pImpl->m_aResults.size() > i_nIndex ) 288 // result already present. 289 return sal_True; 290 291 return sal_False; 292 } 293 294 //------------------------------------------------------------------------------------------------------------------ 295 sal_uInt32 DataSupplier::totalCount() 296 { 297 ::osl::ClearableGuard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); 298 return m_pImpl->m_aResults.size(); 299 } 300 301 //------------------------------------------------------------------------------------------------------------------ 302 sal_uInt32 DataSupplier::currentCount() 303 { 304 return m_pImpl->m_aResults.size(); 305 } 306 307 //------------------------------------------------------------------------------------------------------------------ 308 sal_Bool DataSupplier::isCountFinal() 309 { 310 return sal_True; 311 } 312 313 //------------------------------------------------------------------------------------------------------------------ 314 Reference< XRow > DataSupplier::queryPropertyValues( sal_uInt32 i_nIndex ) 315 { 316 ::osl::MutexGuard aGuard( m_pImpl->m_aMutex ); 317 ENSURE_OR_RETURN( i_nIndex < m_pImpl->m_aResults.size(), "DataSupplier::queryPropertyValues: illegal index!", NULL ); 318 319 Reference< XRow > xRow = m_pImpl->m_aResults[ i_nIndex ].xRow; 320 if ( xRow.is() ) 321 return xRow; 322 323 ENSURE_OR_RETURN( queryContent( i_nIndex ).is(), "could not retrieve the content", NULL ); 324 325 switch ( m_pImpl->m_xContent->getExtensionContentType() ) 326 { 327 case E_ROOT: 328 { 329 const ::rtl::OUString& rId( m_pImpl->m_aResults[ i_nIndex ].sId ); 330 const ::rtl::OUString sRootURL( ContentProvider::getRootURL() ); 331 ::rtl::OUString sTitle = Content::decodeIdentifier( rId.copy( sRootURL.getLength() ) ); 332 if ( ( sTitle.getLength() > 0 ) && ( sTitle[ sTitle.getLength() - 1 ] == '/' ) ) 333 sTitle = sTitle.copy( 0, sTitle.getLength() - 1 ); 334 xRow = Content::getArtificialNodePropertyValues( m_pImpl->m_xSMgr, getResultSet()->getProperties(), sTitle ); 335 } 336 break; 337 338 case E_EXTENSION_ROOT: 339 case E_EXTENSION_CONTENT: 340 { 341 xRow = m_pImpl->m_aResults[ i_nIndex ].pContent->getPropertyValues( 342 getResultSet()->getProperties(), getResultSet()->getEnvironment() ); 343 } 344 break; 345 default: 346 OSL_ENSURE( false, "DataSupplier::queryPropertyValues: unhandled case!" ); 347 break; 348 } 349 350 m_pImpl->m_aResults[ i_nIndex ].xRow = xRow; 351 return xRow; 352 } 353 354 //------------------------------------------------------------------------------------------------------------------ 355 void DataSupplier::releasePropertyValues( sal_uInt32 i_nIndex ) 356 { 357 ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); 358 359 if ( i_nIndex < m_pImpl->m_aResults.size() ) 360 m_pImpl->m_aResults[ i_nIndex ].xRow.clear(); 361 } 362 363 //------------------------------------------------------------------------------------------------------------------ 364 void DataSupplier::close() 365 { 366 } 367 368 //------------------------------------------------------------------------------------------------------------------ 369 void DataSupplier::validate() throw( ResultSetException ) 370 { 371 } 372 373 //...................................................................................................................... 374 } } } // namespace ucp::ext 375 //...................................................................................................................... 376