/************************************************************************* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include "precompiled_ucb.hxx" #include "ucpext_datasupplier.hxx" #include "ucpext_content.hxx" #include "ucpext_provider.hxx" /** === begin UNO includes === **/ #include /** === end UNO includes === **/ #include #include #include #include #include #include #include #include #include //...................................................................................................................... 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 //......................................................................................................................