| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "precompiled_ucb.hxx" |
| |
| #include "ucpext_datasupplier.hxx" |
| #include "ucpext_content.hxx" |
| #include "ucpext_provider.hxx" |
| |
| /** === begin UNO includes === **/ |
| #include <com/sun/star/deployment/XPackageInformationProvider.hpp> |
| /** === end UNO includes === **/ |
| |
| #include <ucbhelper/contentidentifier.hxx> |
| #include <comphelper/componentcontext.hxx> |
| #include <ucbhelper/providerhelper.hxx> |
| #include <ucbhelper/content.hxx> |
| #include <ucbhelper/propertyvalueset.hxx> |
| #include <tools/diagnose_ex.h> |
| #include <rtl/ustrbuf.hxx> |
| |
| #include <vector> |
| #include <boost/shared_ptr.hpp> |
| |
| //...................................................................................................................... |
| namespace ucb { namespace ucp { namespace ext |
| { |
| //...................................................................................................................... |
| |
| /** === begin UNO using === **/ |
| using ::com::sun::star::uno::Reference; |
| using ::com::sun::star::uno::XInterface; |
| using ::com::sun::star::uno::UNO_QUERY; |
| using ::com::sun::star::uno::UNO_QUERY_THROW; |
| using ::com::sun::star::uno::UNO_SET_THROW; |
| using ::com::sun::star::uno::Exception; |
| using ::com::sun::star::uno::RuntimeException; |
| using ::com::sun::star::uno::Any; |
| using ::com::sun::star::uno::makeAny; |
| using ::com::sun::star::uno::Sequence; |
| using ::com::sun::star::uno::Type; |
| using ::com::sun::star::ucb::XContent; |
| using ::com::sun::star::ucb::XContentIdentifier; |
| using ::com::sun::star::sdbc::XRow; |
| using ::com::sun::star::lang::XMultiServiceFactory; |
| using ::com::sun::star::ucb::IllegalIdentifierException; |
| using ::com::sun::star::ucb::ResultSetException; |
| using ::com::sun::star::deployment::XPackageInformationProvider; |
| using ::com::sun::star::beans::Property; |
| using ::com::sun::star::sdbc::XResultSet; |
| using ::com::sun::star::sdbc::XRow; |
| using ::com::sun::star::ucb::XCommandEnvironment; |
| /** === end UNO using === **/ |
| //================================================================================================================== |
| //= ResultListEntry |
| //================================================================================================================== |
| struct ResultListEntry |
| { |
| ::rtl::OUString sId; |
| Reference< XContentIdentifier > xId; |
| ::rtl::Reference< Content > pContent; |
| Reference< XRow > xRow; |
| }; |
| |
| typedef ::std::vector< ResultListEntry > ResultList; |
| |
| //================================================================================================================== |
| //= DataSupplier_Impl |
| //================================================================================================================== |
| struct DataSupplier_Impl |
| { |
| ::osl::Mutex m_aMutex; |
| ResultList m_aResults; |
| ::rtl::Reference< Content > m_xContent; |
| Reference< XMultiServiceFactory > m_xSMgr; |
| sal_Int32 m_nOpenMode; |
| |
| DataSupplier_Impl( const Reference< XMultiServiceFactory >& i_rORB, const ::rtl::Reference< Content >& i_rContent, |
| const sal_Int32 i_nOpenMode ) |
| :m_xContent( i_rContent ) |
| ,m_xSMgr( i_rORB ) |
| ,m_nOpenMode( i_nOpenMode ) |
| { |
| } |
| ~DataSupplier_Impl(); |
| }; |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| DataSupplier_Impl::~DataSupplier_Impl() |
| { |
| } |
| |
| //================================================================================================================== |
| //= helper |
| //================================================================================================================== |
| namespace |
| { |
| ::rtl::OUString lcl_compose( const ::rtl::OUString& i_rBaseURL, const ::rtl::OUString& i_rRelativeURL ) |
| { |
| ENSURE_OR_RETURN( i_rBaseURL.getLength(), "illegal base URL", i_rRelativeURL ); |
| |
| ::rtl::OUStringBuffer aComposer( i_rBaseURL ); |
| if ( i_rBaseURL.getStr()[ i_rBaseURL.getLength() - 1 ] != '/' ) |
| aComposer.append( sal_Unicode( '/' ) ); |
| aComposer.append( i_rRelativeURL ); |
| return aComposer.makeStringAndClear(); |
| } |
| } |
| |
| |
| //================================================================================================================== |
| //= DataSupplier |
| //================================================================================================================== |
| //------------------------------------------------------------------------------------------------------------------ |
| DataSupplier::DataSupplier( const Reference< XMultiServiceFactory >& i_rORB, |
| const ::rtl::Reference< Content >& i_rContent, |
| const sal_Int32 i_nOpenMode ) |
| :m_pImpl( new DataSupplier_Impl( i_rORB, i_rContent, i_nOpenMode ) ) |
| { |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void DataSupplier::fetchData() |
| { |
| try |
| { |
| const ::comphelper::ComponentContext aContext( m_pImpl->m_xSMgr ); |
| const Reference< XPackageInformationProvider > xPackageInfo( |
| aContext.getSingleton( "com.sun.star.deployment.PackageInformationProvider" ), UNO_QUERY_THROW ); |
| |
| const ::rtl::OUString sContentIdentifier( m_pImpl->m_xContent->getIdentifier()->getContentIdentifier() ); |
| |
| switch ( m_pImpl->m_xContent->getExtensionContentType() ) |
| { |
| case E_ROOT: |
| { |
| Sequence< Sequence< ::rtl::OUString > > aExtensionInfo( xPackageInfo->getExtensionList() ); |
| for ( const Sequence< ::rtl::OUString >* pExtInfo = aExtensionInfo.getConstArray(); |
| pExtInfo != aExtensionInfo.getConstArray() + aExtensionInfo.getLength(); |
| ++pExtInfo |
| ) |
| { |
| ENSURE_OR_CONTINUE( pExtInfo->getLength() > 0, "illegal extension info" ); |
| |
| const ::rtl::OUString& rLocalId = (*pExtInfo)[0]; |
| ResultListEntry aEntry; |
| aEntry.sId = ContentProvider::getRootURL() + Content::encodeIdentifier( rLocalId ) + ::rtl::OUString( sal_Unicode( '/' ) ); |
| m_pImpl->m_aResults.push_back( aEntry ); |
| } |
| } |
| break; |
| case E_EXTENSION_ROOT: |
| case E_EXTENSION_CONTENT: |
| { |
| const ::rtl::OUString sPackageLocation( m_pImpl->m_xContent->getPhysicalURL() ); |
| ::ucbhelper::Content aWrappedContent( sPackageLocation, getResultSet()->getEnvironment() ); |
| |
| // obtain the properties which our result set is set up for from the wrapped content |
| Sequence< ::rtl::OUString > aPropertyNames(1); |
| aPropertyNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ); |
| |
| const Reference< XResultSet > xFolderContent( aWrappedContent.createCursor( aPropertyNames ), UNO_SET_THROW ); |
| const Reference< XRow > xContentRow( xFolderContent, UNO_QUERY_THROW ); |
| while ( xFolderContent->next() ) |
| { |
| ResultListEntry aEntry; |
| aEntry.sId = lcl_compose( sContentIdentifier, xContentRow->getString( 1 ) ); |
| m_pImpl->m_aResults.push_back( aEntry ); |
| } |
| } |
| break; |
| default: |
| OSL_ENSURE( false, "DataSupplier::fetchData: unimplemented content type!" ); |
| break; |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| DataSupplier::~DataSupplier() |
| { |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| ::rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 i_nIndex ) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); |
| |
| if ( i_nIndex < m_pImpl->m_aResults.size() ) |
| { |
| const ::rtl::OUString sId = m_pImpl->m_aResults[ i_nIndex ].sId; |
| if ( sId.getLength() ) |
| return sId; |
| } |
| |
| OSL_ENSURE( false, "DataSupplier::queryContentIdentifierString: illegal index, or illegal result entry id!" ); |
| return ::rtl::OUString(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| Reference< XContentIdentifier > DataSupplier::queryContentIdentifier( sal_uInt32 i_nIndex ) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); |
| |
| if ( i_nIndex < m_pImpl->m_aResults.size() ) |
| { |
| Reference< XContentIdentifier > xId( m_pImpl->m_aResults[ i_nIndex ].xId ); |
| if ( xId.is() ) |
| return xId; |
| } |
| |
| ::rtl::OUString sId = queryContentIdentifierString( i_nIndex ); |
| if ( sId.getLength() ) |
| { |
| Reference< XContentIdentifier > xId = new ::ucbhelper::ContentIdentifier( sId ); |
| m_pImpl->m_aResults[ i_nIndex ].xId = xId; |
| return xId; |
| } |
| |
| return Reference< XContentIdentifier >(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| Reference< XContent > DataSupplier::queryContent( sal_uInt32 i_nIndex ) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); |
| ENSURE_OR_RETURN( i_nIndex < m_pImpl->m_aResults.size(), "illegal index!", NULL ); |
| |
| |
| ::rtl::Reference< Content > pContent( m_pImpl->m_aResults[ i_nIndex ].pContent ); |
| if ( pContent.is() ) |
| return pContent.get(); |
| |
| Reference< XContentIdentifier > xId( queryContentIdentifier( i_nIndex ) ); |
| if ( xId.is() ) |
| { |
| try |
| { |
| Reference< XContent > xContent( m_pImpl->m_xContent->getProvider()->queryContent( xId ) ); |
| pContent.set( dynamic_cast< Content* >( xContent.get() ) ); |
| OSL_ENSURE( pContent.is() || !xContent.is(), "DataSupplier::queryContent: invalid content implementation!" ); |
| m_pImpl->m_aResults[ i_nIndex ].pContent = pContent; |
| return pContent.get(); |
| |
| } |
| catch ( const IllegalIdentifierException& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| return Reference< XContent >(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| sal_Bool DataSupplier::getResult( sal_uInt32 i_nIndex ) |
| { |
| ::osl::ClearableGuard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); |
| |
| if ( m_pImpl->m_aResults.size() > i_nIndex ) |
| // result already present. |
| return sal_True; |
| |
| return sal_False; |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| sal_uInt32 DataSupplier::totalCount() |
| { |
| ::osl::ClearableGuard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); |
| return m_pImpl->m_aResults.size(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| sal_uInt32 DataSupplier::currentCount() |
| { |
| return m_pImpl->m_aResults.size(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| sal_Bool DataSupplier::isCountFinal() |
| { |
| return sal_True; |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| Reference< XRow > DataSupplier::queryPropertyValues( sal_uInt32 i_nIndex ) |
| { |
| ::osl::MutexGuard aGuard( m_pImpl->m_aMutex ); |
| ENSURE_OR_RETURN( i_nIndex < m_pImpl->m_aResults.size(), "DataSupplier::queryPropertyValues: illegal index!", NULL ); |
| |
| Reference< XRow > xRow = m_pImpl->m_aResults[ i_nIndex ].xRow; |
| if ( xRow.is() ) |
| return xRow; |
| |
| ENSURE_OR_RETURN( queryContent( i_nIndex ).is(), "could not retrieve the content", NULL ); |
| |
| switch ( m_pImpl->m_xContent->getExtensionContentType() ) |
| { |
| case E_ROOT: |
| { |
| const ::rtl::OUString& rId( m_pImpl->m_aResults[ i_nIndex ].sId ); |
| const ::rtl::OUString sRootURL( ContentProvider::getRootURL() ); |
| ::rtl::OUString sTitle = Content::decodeIdentifier( rId.copy( sRootURL.getLength() ) ); |
| if ( ( sTitle.getLength() > 0 ) && ( sTitle[ sTitle.getLength() - 1 ] == '/' ) ) |
| sTitle = sTitle.copy( 0, sTitle.getLength() - 1 ); |
| xRow = Content::getArtificialNodePropertyValues( m_pImpl->m_xSMgr, getResultSet()->getProperties(), sTitle ); |
| } |
| break; |
| |
| case E_EXTENSION_ROOT: |
| case E_EXTENSION_CONTENT: |
| { |
| xRow = m_pImpl->m_aResults[ i_nIndex ].pContent->getPropertyValues( |
| getResultSet()->getProperties(), getResultSet()->getEnvironment() ); |
| } |
| break; |
| default: |
| OSL_ENSURE( false, "DataSupplier::queryPropertyValues: unhandled case!" ); |
| break; |
| } |
| |
| m_pImpl->m_aResults[ i_nIndex ].xRow = xRow; |
| return xRow; |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void DataSupplier::releasePropertyValues( sal_uInt32 i_nIndex ) |
| { |
| ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); |
| |
| if ( i_nIndex < m_pImpl->m_aResults.size() ) |
| m_pImpl->m_aResults[ i_nIndex ].xRow.clear(); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void DataSupplier::close() |
| { |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| void DataSupplier::validate() throw( ResultSetException ) |
| { |
| } |
| |
| //...................................................................................................................... |
| } } } // namespace ucp::ext |
| //...................................................................................................................... |