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