diff options
author | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2010-03-25 08:49:40 +0100 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2010-03-25 08:49:40 +0100 |
commit | 667e864a12c4a0c2c90e49080e3000fc9cb26cb2 (patch) | |
tree | b2fe6e4aa8b83de426b629dc1a796fcc3ebe4e26 /ucb | |
parent | ad195dcdbcb178b2df5602babb825863096f1c7a (diff) |
slidecopy: extended the Extensions-UCP so it now allows browsing the complete hierarchy. File access still missing
Diffstat (limited to 'ucb')
-rw-r--r-- | ucb/source/ucp/ext/ucpext_content.cxx | 229 | ||||
-rw-r--r-- | ucb/source/ucp/ext/ucpext_content.hxx | 76 | ||||
-rw-r--r-- | ucb/source/ucp/ext/ucpext_datasupplier.cxx | 129 | ||||
-rw-r--r-- | ucb/source/ucp/ext/ucpext_datasupplier.hxx | 4 | ||||
-rw-r--r-- | ucb/source/ucp/ext/ucpext_provider.cxx | 12 | ||||
-rw-r--r-- | ucb/source/ucp/ext/ucpext_provider.hxx | 4 | ||||
-rw-r--r-- | ucb/source/ucp/ext/ucpext_resultset.cxx | 12 |
7 files changed, 378 insertions, 88 deletions
diff --git a/ucb/source/ucp/ext/ucpext_content.cxx b/ucb/source/ucp/ext/ucpext_content.cxx index 27579f2a1d9f..1611fe579dbd 100644 --- a/ucb/source/ucp/ext/ucpext_content.cxx +++ b/ucb/source/ucp/ext/ucpext_content.cxx @@ -49,13 +49,19 @@ #include <com/sun/star/ucb/OpenMode.hpp> #include <com/sun/star/ucb/XDynamicResultSet.hpp> #include <com/sun/star/lang/IllegalAccessException.hpp> +#include <com/sun/star/deployment/XPackageInformationProvider.hpp> /** === end UNO includes === **/ #include <ucbhelper/contentidentifier.hxx> #include <ucbhelper/propertyvalueset.hxx> #include <ucbhelper/cancelcommandexecution.hxx> +#include <ucbhelper/content.hxx> #include <tools/diagnose_ex.h> #include <comphelper/string.hxx> +#include <comphelper/componentcontext.hxx> +#include <rtl/ustrbuf.hxx> + +#include <algorithm> //...................................................................................................................... namespace ucb { namespace ucp { namespace ext @@ -97,18 +103,77 @@ namespace ucb { namespace ucp { namespace ext using ::com::sun::star::beans::PropertyChangeEvent; using ::com::sun::star::lang::IllegalAccessException; using ::com::sun::star::ucb::CommandInfo; + using ::com::sun::star::deployment::XPackageInformationProvider; /** === end UNO using === **/ namespace OpenMode = ::com::sun::star::ucb::OpenMode; namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute; //================================================================================================================== + //= 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(); + } + + //-------------------------------------------------------------------------------------------------------------- + struct SelectPropertyName : public ::std::unary_function< Property, ::rtl::OUString > + { + const ::rtl::OUString& operator()( const Property& i_rProperty ) const + { + return i_rProperty.Name; + } + }; + } + + //================================================================================================================== //= Content //================================================================================================================== //------------------------------------------------------------------------------------------------------------------ Content::Content( const Reference< XMultiServiceFactory >& i_rORB, ::ucbhelper::ContentProviderImplHelper* i_pProvider, const Reference< XContentIdentifier >& i_rIdentifier ) :Content_Base( i_rORB, i_pProvider, i_rIdentifier ) + ,m_eExtContentType( E_UNKNOWN ) + ,m_aIsFolder() + ,m_aContentType() + ,m_sExtensionId() + ,m_sPathIntoExtension() { + if ( denotesRootContent( getIdentifier() ) ) + { + m_eExtContentType = E_ROOT; + } + else if ( denotesRootContent( getParentURL() ) ) + { + m_eExtContentType = E_EXTENSION_ROOT; + } + else + { + m_eExtContentType = E_EXTENSION_CONTENT; + } + + if ( m_eExtContentType != E_ROOT ) + { + const ::rtl::OUString sRootURL = ContentProvider::getRootURL(); + m_sExtensionId = getIdentifier()->getContentIdentifier().copy( sRootURL.getLength() ); + + const sal_Int32 nNextSep = m_sExtensionId.indexOf( '/' ); + if ( nNextSep > -1 ) + { + m_sPathIntoExtension = m_sExtensionId.copy( nNextSep + 1 ); + m_sExtensionId = m_sExtensionId.copy( 0, nNextSep ); + } + m_sExtensionId = Content::deescapeIdentifier( m_sExtensionId ); + } } //------------------------------------------------------------------------------------------------------------------ @@ -134,7 +199,8 @@ namespace ucb { namespace ucp { namespace ext //------------------------------------------------------------------------------------------------------------------ ::rtl::OUString SAL_CALL Content::getContentType() throw( RuntimeException ) { - return m_aProps.aContentType; + impl_determineContentType(); + return *m_aContentType; } //------------------------------------------------------------------------------------------------------------------ @@ -204,7 +270,7 @@ namespace ucb { namespace ucp { namespace ext ( aOpenCommand.Mode == OpenMode::DOCUMENTS ) ); - if ( bOpenFolder && m_aProps.bIsFolder ) + if ( bOpenFolder && impl_isFolder() ) { Reference< XDynamicResultSet > xSet = new ResultSet( m_xSMgr, this, aOpenCommand, i_rEvironment ); @@ -231,6 +297,7 @@ namespace ucb { namespace ucp { namespace ext Reference< XOutputStream > xOut( aOpenCommand.Sink, UNO_QUERY ); if ( xOut.is() ) { + OSL_ENSURE( false, "Content::execute( open->out ): not implemented!" ); // TODO: write data into xOut } else @@ -241,6 +308,7 @@ namespace ucb { namespace ucp { namespace ext Reference< XInputStream > xIn /* @@@ your XInputStream + XSeekable impl. object */; // TODO + OSL_ENSURE( false, "Content::execute( open->sink ): not implemented!" ); xDataSink->setInputStream( xIn ); } else @@ -284,26 +352,43 @@ namespace ucb { namespace ucp { namespace ext } //------------------------------------------------------------------------------------------------------------------ - bool Content::denotesRootContent( const Reference< XContentIdentifier >& i_rIdentifier ) + ::rtl::OUString Content::deescapeIdentifier( const ::rtl::OUString& i_rIdentifier ) + { + const ::rtl::OUString sQuoteQuotes = ::comphelper::string::searchAndReplaceAllAsciiWithAscii( + i_rIdentifier, "%%", "%" ); + const ::rtl::OUString sQuoteSlashes = ::comphelper::string::searchAndReplaceAllAsciiWithAscii( + i_rIdentifier, "%47", "/" ); + return sQuoteSlashes; + } + + //------------------------------------------------------------------------------------------------------------------ + bool Content::denotesRootContent( const ::rtl::OUString& i_rContentIdentifier ) { const sal_Char* pScheme = "vnd.oracle.ooo.extension"; const sal_Int32 nSchemeLength = sizeof( "vnd.oracle.ooo.extension" ) - 1; - const ::rtl::OUString sIdentifier( i_rIdentifier->getContentIdentifier() ); - ENSURE_OR_RETURN_FALSE( sIdentifier.matchAsciiL( pScheme, nSchemeLength ), "illegal content URL" ); - return sIdentifier.copy( nSchemeLength ).equalsAsciiL( ":/", 2 ); + ENSURE_OR_RETURN_FALSE( i_rContentIdentifier.matchAsciiL( pScheme, nSchemeLength ), "illegal content URL" ); + return i_rContentIdentifier.copy( nSchemeLength ).equalsAsciiL( ":/", 2 ); } //------------------------------------------------------------------------------------------------------------------ ::rtl::OUString Content::getParentURL() { const ::rtl::OUString sURL = m_xIdentifier->getContentIdentifier(); - const ::rtl::OUString sParentURL( sURL.copy( 0, sURL.lastIndexOf( '/' ) + 1 ) ); + ENSURE_OR_RETURN( sURL.getLength(), "unexpected content URL", ::rtl::OUString() ); + sal_Int32 nCopyUpTo = sURL.lastIndexOf( '/' ) + 1; + if ( ( nCopyUpTo == sURL.getLength() ) && ( nCopyUpTo > 1 ) ) + { + nCopyUpTo = sURL.lastIndexOf( '/', nCopyUpTo - 2 ) + 1; + if ( nCopyUpTo == 0 ) + nCopyUpTo = sURL.getLength(); + } + const ::rtl::OUString sParentURL( sURL.copy( 0, nCopyUpTo ) ); return sParentURL; } //------------------------------------------------------------------------------------------------------------------ - Reference< XRow > Content::getPropertyValues( const Reference< XMultiServiceFactory >& i_rORB, - const Sequence< Property >& i_rProperties, const ContentProperties& i_rData ) + Reference< XRow > Content::getArtificialNodePropertyValues( const Reference< XMultiServiceFactory >& i_rORB, + const Sequence< Property >& i_rProperties, const ::rtl::OUString& i_rTitle ) { // note: empty sequence means "get values of all supported properties". ::rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( i_rORB ); @@ -321,19 +406,19 @@ namespace ucb { namespace ucp { namespace ext // Process Core properties. if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ) { - xRow->appendString ( rProp, i_rData.aContentType ); + xRow->appendString ( rProp, ContentProvider::getArtificialNodeContentType() ); } else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) { - xRow->appendString ( rProp, i_rData.aTitle ); + xRow->appendString ( rProp, i_rTitle ); } else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ) { - xRow->appendBoolean( rProp, i_rData.bIsDocument ); + xRow->appendBoolean( rProp, sal_False ); } else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) { - xRow->appendBoolean( rProp, i_rData.bIsFolder ); + xRow->appendBoolean( rProp, sal_True ); } else { @@ -349,34 +434,86 @@ namespace ucb { namespace ucp { namespace ext -1, getCppuType( static_cast< const ::rtl::OUString * >( 0 ) ), PropertyAttribute::BOUND | PropertyAttribute::READONLY ), - i_rData.aContentType ); + ContentProvider::getArtificialNodeContentType() ); xRow->appendString ( Property( ::rtl::OUString::createFromAscii( "Title" ), -1, getCppuType( static_cast< const ::rtl::OUString * >( 0 ) ), PropertyAttribute::BOUND | PropertyAttribute::READONLY ), - i_rData.aTitle ); + i_rTitle ); xRow->appendBoolean( Property( ::rtl::OUString::createFromAscii( "IsDocument" ), -1, getCppuBooleanType(), PropertyAttribute::BOUND | PropertyAttribute::READONLY ), - i_rData.bIsDocument ); + sal_False ); xRow->appendBoolean( Property( ::rtl::OUString::createFromAscii( "IsFolder" ), -1, getCppuBooleanType(), PropertyAttribute::BOUND | PropertyAttribute::READONLY ), - i_rData.bIsFolder ); + sal_True ); } return Reference< XRow >( xRow.get() ); } //------------------------------------------------------------------------------------------------------------------ - Reference< XRow > Content::getPropertyValues( const Sequence< Property >& i_rProperties, const Reference< XCommandEnvironment >& /* xEnv */) + ::rtl::OUString Content::getPhysicalURL() const { - osl::Guard< osl::Mutex > aGuard( m_aMutex ); - return getPropertyValues( m_xSMgr, - i_rProperties, - m_aProps ); + ENSURE_OR_RETURN( m_eExtContentType != E_ROOT, "illegal call", ::rtl::OUString() ); + + // create an ucb::XContent for the physical file within the deployed extension + const ::comphelper::ComponentContext aContext( m_xSMgr ); + const Reference< XPackageInformationProvider > xPackageInfo( + aContext.getSingleton( "com.sun.star.deployment.PackageInformationProvider" ), UNO_QUERY_THROW ); + const ::rtl::OUString sPackageLocation( xPackageInfo->getPackageLocation( m_sExtensionId ) ); + + if ( m_sPathIntoExtension.getLength() == 0 ) + return sPackageLocation; + return lcl_compose( sPackageLocation, m_sPathIntoExtension ); + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XRow > Content::getPropertyValues( const Sequence< Property >& i_rProperties, const Reference< XCommandEnvironment >& i_rEnv ) + { + ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex ); + + switch ( m_eExtContentType ) + { + case E_ROOT: + return getArtificialNodePropertyValues( m_xSMgr, i_rProperties, ContentProvider::getRootURL() ); + case E_EXTENSION_ROOT: + return getArtificialNodePropertyValues( m_xSMgr, i_rProperties, m_sExtensionId ); + case E_EXTENSION_CONTENT: + { + const ::rtl::OUString sPhysicalContentURL( getPhysicalURL() ); + ::ucbhelper::Content aRequestedContent( sPhysicalContentURL, i_rEnv ); + + // translate the property request + Sequence< ::rtl::OUString > aPropertyNames( i_rProperties.getLength() ); + ::std::transform( + i_rProperties.getConstArray(), + i_rProperties.getConstArray() + i_rProperties.getLength(), + aPropertyNames.getArray(), + SelectPropertyName() + ); + const Sequence< Any > aPropertyValues = aRequestedContent.getPropertyValues( aPropertyNames ); + const ::rtl::Reference< ::ucbhelper::PropertyValueSet > xValueRow = new ::ucbhelper::PropertyValueSet( m_xSMgr ); + sal_Int32 i=0; + for ( const Any* value = aPropertyValues.getConstArray(); + value != aPropertyValues.getConstArray() + aPropertyValues.getLength(); + ++value, ++i + ) + { + xValueRow->appendObject( aPropertyNames[i], *value ); + } + return xValueRow.get(); + } + break; + default: + OSL_ENSURE( false, "Content::getPropertyValues: unhandled case!" ); + } + + OSL_ENSURE( false, "Content::getPropertyValues: unreachable!" ); + return NULL; } //------------------------------------------------------------------------------------------------------------------ @@ -438,14 +575,11 @@ namespace ucb { namespace ucp { namespace ext /////////////////////////////////////////////////////////////// // Optional standard commands /////////////////////////////////////////////////////////////// - - #ifdef IMPLEMENT_COMMAND_OPEN , CommandInfo( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ), -1, getCppuType( static_cast< OpenCommandArgument2 * >( 0 ) ) ) - #endif }; return Sequence< CommandInfo >( aCommandInfoTable, nCommandCount ); @@ -484,6 +618,51 @@ namespace ucb { namespace ucp { namespace ext return Sequence< Property >( aProperties, sizeof( aProperties ) / sizeof( aProperties[0] ) ); } + //------------------------------------------------------------------------------------------------------------------ + bool Content::impl_isFolder() + { + if ( !!m_aIsFolder ) + return *m_aIsFolder; + + bool bIsFolder = false; + try + { + Sequence< Property > aProps(1); + aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ); + Reference< XRow > xRow( getPropertyValues( aProps, NULL ), UNO_SET_THROW ); + bIsFolder = xRow->getBoolean(1); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + m_aIsFolder.reset( bIsFolder ); + return *m_aIsFolder; + } + + //------------------------------------------------------------------------------------------------------------------ + void Content::impl_determineContentType() + { + if ( !!m_aContentType ) + return; + + m_aContentType.reset( ContentProvider::getArtificialNodeContentType() ); + if ( m_eExtContentType == E_EXTENSION_CONTENT ) + { + try + { + Sequence< Property > aProps(1); + aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ); + Reference< XRow > xRow( getPropertyValues( aProps, NULL ), UNO_SET_THROW ); + m_aContentType.reset( xRow->getString(1) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + //...................................................................................................................... } } } // namespace ucp::ext //...................................................................................................................... diff --git a/ucb/source/ucp/ext/ucpext_content.hxx b/ucb/source/ucp/ext/ucpext_content.hxx index 9b5667a1d641..8e3e8fa386c7 100644 --- a/ucb/source/ucp/ext/ucpext_content.hxx +++ b/ucb/source/ucp/ext/ucpext_content.hxx @@ -36,6 +36,7 @@ #include <ucbhelper/contenthelper.hxx> #include <list> +#include <boost/optional.hpp> //...................................................................................................................... namespace ucb { namespace ucp { namespace ext @@ -43,20 +44,15 @@ namespace ucb { namespace ucp { namespace ext //...................................................................................................................... //================================================================================================================== - //= ContentProvider + //= ExtensionContentType //================================================================================================================== - struct ContentProperties + enum ExtensionContentType { - ::rtl::OUString aTitle; // Title - ::rtl::OUString aContentType; // ContentType - bool bIsDocument; // IsDocument - bool bIsFolder; // IsFolder - - ContentProperties() - :bIsDocument( false ) - ,bIsFolder( true ) - { - } + E_ROOT, + E_EXTENSION_ROOT, + E_EXTENSION_CONTENT, + + E_UNKNOWN }; //================================================================================================================== @@ -66,23 +62,38 @@ namespace ucb { namespace ucp { namespace ext class Content : public Content_Base { public: - static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow > - getPropertyValues( - const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSMgr, - const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& rProperties, - const ContentProperties& rData - ); - Content( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, ::ucbhelper::ContentProviderImplHelper* pProvider, const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentIdentifier >& Identifier ); - static bool denotesRootContent( const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentIdentifier >& i_rIdentifier ); + static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow > + getArtificialNodePropertyValues( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSMgr, + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& rProperties, + const ::rtl::OUString& rTitle + ); + + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow > + getPropertyValues( + const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& rProperties, + const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >& xEnv + ); static ::rtl::OUString escapeIdentifier( const ::rtl::OUString& i_rIdentifier ); + static ::rtl::OUString + deescapeIdentifier( const ::rtl::OUString& i_rIdentifier ); + + virtual ::rtl::OUString getParentURL(); + + ExtensionContentType getExtensionContentType() const { return m_eExtContentType; } + + /** retrieves the URL of the underlying physical content. Not to be called when getExtensionContentType() + returns E_ROOT. + */ + ::rtl::OUString getPhysicalURL() const; protected: virtual ~Content(); @@ -113,28 +124,31 @@ namespace ucb { namespace ucp { namespace ext throw ( ::com::sun::star::uno::RuntimeException ); - protected: - const ContentProperties& getProperties() const { return m_aProps; } - ContentProperties& getProperties() { return m_aProps; } - private: virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > getProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >& i_rEnv ); virtual ::com::sun::star::uno::Sequence< ::com::sun::star::ucb::CommandInfo > getCommands( const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >& i_rEnv ); - virtual ::rtl::OUString getParentURL(); - ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow > - getPropertyValues( - const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& rProperties, - const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >& xEnv - ); ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rValues, const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >& xEnv ); + static bool denotesRootContent( const ::rtl::OUString& i_rContentIdentifier ); + static bool denotesRootContent( const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentIdentifier >& i_rIdentifier ) + { + return denotesRootContent( i_rIdentifier->getContentIdentifier() ); + } + + bool impl_isFolder(); + void impl_determineContentType(); + private: - ContentProperties m_aProps; + ExtensionContentType m_eExtContentType; + ::boost::optional< bool > m_aIsFolder; + ::boost::optional< ::rtl::OUString > m_aContentType; + ::rtl::OUString m_sExtensionId; + ::rtl::OUString m_sPathIntoExtension; }; //...................................................................................................................... diff --git a/ucb/source/ucp/ext/ucpext_datasupplier.cxx b/ucb/source/ucp/ext/ucpext_datasupplier.cxx index d40e2339fe70..3c99c95197ee 100644 --- a/ucb/source/ucp/ext/ucpext_datasupplier.cxx +++ b/ucb/source/ucp/ext/ucpext_datasupplier.cxx @@ -28,6 +28,7 @@ #include "ucpext_datasupplier.hxx" #include "ucpext_content.hxx" +#include "ucpext_provider.hxx" /** === begin UNO includes === **/ #include <com/sun/star/deployment/XPackageInformationProvider.hpp> @@ -36,9 +37,13 @@ #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 @@ -65,8 +70,10 @@ namespace ucb { namespace ucp { namespace ext 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 //================================================================================================================== @@ -74,15 +81,8 @@ namespace ucb { namespace ucp { namespace ext { ::rtl::OUString sId; Reference< XContentIdentifier > xId; - ContentProperties aProperties; - Reference< XContent > xContent; + ::rtl::Reference< Content > pContent; Reference< XRow > xRow; - - ResultListEntry( const ::rtl::OUString& i_rParentId, const ::rtl::OUString& i_rLocalId ) - { - aProperties.aTitle = i_rLocalId; - sId = i_rParentId + Content::escapeIdentifier( i_rLocalId ); - } }; typedef ::std::vector< ResultListEntry > ResultList; @@ -114,6 +114,24 @@ namespace ucb { namespace ucp { namespace ext } //================================================================================================================== + //= 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 //================================================================================================================== //------------------------------------------------------------------------------------------------------------------ @@ -122,16 +140,23 @@ namespace ucb { namespace ucp { namespace ext const sal_Int32 i_nOpenMode ) :m_pImpl( new DataSupplier_Impl( i_rORB, i_rContent, i_nOpenMode ) ) { + } + + //------------------------------------------------------------------------------------------------------------------ + void DataSupplier::fetchData() + { try { - if ( Content::denotesRootContent( m_pImpl->m_xContent->getIdentifier() ) ) - { - const ::rtl::OUString sContentId( m_pImpl->m_xContent->getIdentifier()->getContentIdentifier() ); + const ::comphelper::ComponentContext aContext( m_pImpl->m_xSMgr ); + const Reference< XPackageInformationProvider > xPackageInfo( + aContext.getSingleton( "com.sun.star.deployment.PackageInformationProvider" ), UNO_QUERY_THROW ); - const ::comphelper::ComponentContext aContext( i_rORB ); - 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(); @@ -140,11 +165,37 @@ namespace ucb { namespace ucp { namespace ext { ENSURE_OR_CONTINUE( pExtInfo->getLength() > 0, "illegal extension info" ); - ResultListEntry aEntry( sContentId, (*pExtInfo)[0] ); - aEntry.aProperties.aContentType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.oracle.ooo.extension-content" ) ); - m_pImpl->m_aResults.push_back( ResultListEntry( aEntry ) ); + const ::rtl::OUString& rLocalId = (*pExtInfo)[0]; + ResultListEntry aEntry; + aEntry.sId = lcl_compose( sContentIdentifier, Content::escapeIdentifier( rLocalId ) ); + 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& ) { @@ -202,9 +253,10 @@ namespace ucb { namespace ucp { namespace ext ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); ENSURE_OR_RETURN( i_nIndex < m_pImpl->m_aResults.size(), "illegal index!", NULL ); - Reference< XContent > xContent( m_pImpl->m_aResults[ i_nIndex ].xContent ); - if ( xContent.is() ) - return xContent; + + ::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() ) @@ -212,8 +264,10 @@ namespace ucb { namespace ucp { namespace ext try { Reference< XContent > xContent( m_pImpl->m_xContent->getProvider()->queryContent( xId ) ); - m_pImpl->m_aResults[ i_nIndex ].xContent = xContent; - return xContent; + ::rtl::Reference< Content > pContent( 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& ) @@ -259,15 +313,38 @@ namespace ucb { namespace ucp { namespace ext //------------------------------------------------------------------------------------------------------------------ Reference< XRow > DataSupplier::queryPropertyValues( sal_uInt32 i_nIndex ) { - ::osl::Guard< ::osl::Mutex > aGuard( m_pImpl->m_aMutex ); + ::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; - xRow = Content::getPropertyValues( m_pImpl->m_xSMgr, getResultSet()->getProperties(), - m_pImpl->m_aResults[ i_nIndex ].aProperties ); + 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 sTitle = Content::deescapeIdentifier( rId.copy( rId.indexOf( '/' ) + 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; } diff --git a/ucb/source/ucp/ext/ucpext_datasupplier.hxx b/ucb/source/ucp/ext/ucpext_datasupplier.hxx index 7957a318aa36..526491cd678b 100644 --- a/ucb/source/ucp/ext/ucpext_datasupplier.hxx +++ b/ucb/source/ucp/ext/ucpext_datasupplier.hxx @@ -48,11 +48,13 @@ namespace ucb { namespace ucp { namespace ext { public: DataSupplier( - const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& i_rORB, + const ::com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& i_rORB, const rtl::Reference< Content >& rContent, const sal_Int32 nOpenMode ); + void fetchData(); + protected: virtual ~DataSupplier(); diff --git a/ucb/source/ucp/ext/ucpext_provider.cxx b/ucb/source/ucp/ext/ucpext_provider.cxx index 4e26dacf229c..c7da555d6c28 100644 --- a/ucb/source/ucp/ext/ucpext_provider.cxx +++ b/ucb/source/ucp/ext/ucpext_provider.cxx @@ -111,6 +111,18 @@ namespace ucb { namespace ucp { namespace ext } //------------------------------------------------------------------------------------------------------------------ + ::rtl::OUString ContentProvider::getRootURL() + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.oracle.ooo.extension:/" ) ); + } + + //------------------------------------------------------------------------------------------------------------------ + ::rtl::OUString ContentProvider::getArtificialNodeContentType() + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.oracle.ooo.extension-content" ) ); + } + + //------------------------------------------------------------------------------------------------------------------ Reference< XContent > SAL_CALL ContentProvider::queryContent( const Reference< XContentIdentifier >& i_rIdentifier ) throw( IllegalIdentifierException, RuntimeException ) { diff --git a/ucb/source/ucp/ext/ucpext_provider.hxx b/ucb/source/ucp/ext/ucpext_provider.hxx index 1e9090dab2e0..1f41fdd0f084 100644 --- a/ucb/source/ucp/ext/ucpext_provider.hxx +++ b/ucb/source/ucp/ext/ucpext_provider.hxx @@ -55,6 +55,10 @@ namespace ucb { namespace ucp { namespace ext // XContentProvider virtual ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent > SAL_CALL queryContent( const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContentIdentifier >& Identifier ) throw (::com::sun::star::ucb::IllegalIdentifierException, ::com::sun::star::uno::RuntimeException); + + public: + static ::rtl::OUString getRootURL(); + static ::rtl::OUString getArtificialNodeContentType(); }; //...................................................................................................................... diff --git a/ucb/source/ucp/ext/ucpext_resultset.cxx b/ucb/source/ucp/ext/ucpext_resultset.cxx index 6d5e79d61902..d8a2eb8e9914 100644 --- a/ucb/source/ucp/ext/ucpext_resultset.cxx +++ b/ucb/source/ucp/ext/ucpext_resultset.cxx @@ -73,16 +73,18 @@ namespace ucb { namespace ucp { namespace ext //------------------------------------------------------------------------------------------------------------------ void ResultSet::initStatic() { + ::rtl::Reference< DataSupplier > pDataSupplier( new DataSupplier( + m_xSMgr, + m_xContent, + m_aCommand.Mode + ) ); m_xResultSet1 = new ::ucbhelper::ResultSet( m_xSMgr, m_aCommand.Properties, - new DataSupplier( - m_xSMgr, - m_xContent, - m_aCommand.Mode - ), + pDataSupplier.get(), m_xEnvironment ); + pDataSupplier->fetchData(); } //------------------------------------------------------------------------------------------------------------------ |