diff options
Diffstat (limited to 'ucb/source/ucp/ext')
-rw-r--r-- | ucb/source/ucp/ext/ucpext_content.cxx | 90 | ||||
-rw-r--r-- | ucb/source/ucp/ext/ucpext_content.hxx | 4 | ||||
-rw-r--r-- | ucb/source/ucp/ext/ucpext_datasupplier.cxx | 7 | ||||
-rw-r--r-- | ucb/source/ucp/ext/ucpext_provider.cxx | 61 |
4 files changed, 130 insertions, 32 deletions
diff --git a/ucb/source/ucp/ext/ucpext_content.cxx b/ucb/source/ucp/ext/ucpext_content.cxx index d8076db33ae2..88afe370908b 100644 --- a/ucb/source/ucp/ext/ucpext_content.cxx +++ b/ucb/source/ucp/ext/ucpext_content.cxx @@ -149,23 +149,29 @@ namespace ucb { namespace ucp { namespace ext ,m_sExtensionId() ,m_sPathIntoExtension() { - if ( denotesRootContent( getIdentifier() ) ) + const ::rtl::OUString sURL( getIdentifier()->getContentIdentifier() ); + if ( denotesRootContent( sURL ) ) { m_eExtContentType = E_ROOT; } - else if ( denotesRootContent( getParentURL() ) ) - { - m_eExtContentType = E_EXTENSION_ROOT; - } else { - m_eExtContentType = E_EXTENSION_CONTENT; + const ::rtl::OUString sRelativeURL( sURL.copy( ContentProvider::getRootURL().getLength() ) ); + const sal_Int32 nSepPos = sRelativeURL.indexOf( '/' ); + if ( ( nSepPos == -1 ) || ( nSepPos == sRelativeURL.getLength() - 1 ) ) + { + 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() ); + m_sExtensionId = sURL.copy( sRootURL.getLength() ); const sal_Int32 nNextSep = m_sExtensionId.indexOf( '/' ); if ( nNextSep > -1 ) @@ -322,26 +328,70 @@ namespace ucb { namespace ucp { namespace ext //------------------------------------------------------------------------------------------------------------------ bool Content::denotesRootContent( const ::rtl::OUString& i_rContentIdentifier ) { - const sal_Char* pScheme = "vnd.sun.star.extension"; - const sal_Int32 nSchemeLength = sizeof( "vnd.sun.star.extension" ) - 1; - ENSURE_OR_RETURN_FALSE( i_rContentIdentifier.matchAsciiL( pScheme, nSchemeLength ), "illegal content URL" ); - return i_rContentIdentifier.copy( nSchemeLength ).equalsAsciiL( ":/", 2 ); + const ::rtl::OUString sRootURL( ContentProvider::getRootURL() ); + if ( i_rContentIdentifier == sRootURL ) + return true; + + // the root URL contains only two trailing /, but we also recognize 3 of them as denoting the root URL + if ( i_rContentIdentifier.match( sRootURL ) + && ( i_rContentIdentifier.getLength() == sRootURL.getLength() + 1 ) + && ( i_rContentIdentifier[ i_rContentIdentifier.getLength() - 1 ] == '/' ) + ) + return true; + + return false; } //------------------------------------------------------------------------------------------------------------------ ::rtl::OUString Content::getParentURL() { - const ::rtl::OUString sURL = m_xIdentifier->getContentIdentifier(); - ENSURE_OR_RETURN( sURL.getLength(), "unexpected content URL", ::rtl::OUString() ); - sal_Int32 nCopyUpTo = sURL.lastIndexOf( '/' ) + 1; - if ( ( nCopyUpTo == sURL.getLength() ) && ( nCopyUpTo > 1 ) ) + const ::rtl::OUString sRootURL( ContentProvider::getRootURL() ); + + switch ( m_eExtContentType ) { - nCopyUpTo = sURL.lastIndexOf( '/', nCopyUpTo - 2 ) + 1; - if ( nCopyUpTo == 0 ) - nCopyUpTo = sURL.getLength(); + case E_ROOT: + // don't have a parent + return sRootURL; + + case E_EXTENSION_ROOT: + // our parent is the root itself + return sRootURL; + + case E_EXTENSION_CONTENT: + { + const ::rtl::OUString sURL = m_xIdentifier->getContentIdentifier(); + + // cut the root URL + ENSURE_OR_BREAK( sURL.match( sRootURL, 0 ), "illegal URL structure - no root" ); + ::rtl::OUString sRelativeURL( sURL.copy( sRootURL.getLength() ) ); + + // cut the extension ID + const ::rtl::OUString sSeparatedExtensionId( encodeIdentifier( m_sExtensionId ) + ::rtl::OUString( sal_Unicode( '/' ) ) ); + ENSURE_OR_BREAK( sRelativeURL.match( sSeparatedExtensionId ), "illegal URL structure - no extension ID" ); + sRelativeURL = sRelativeURL.copy( sSeparatedExtensionId.getLength() ); + + // cut the final slash (if any) + ENSURE_OR_BREAK( sRelativeURL.getLength(), "illegal URL structure - ExtensionContent should have a level below the extension ID" ); + if ( sRelativeURL.getStr()[ sRelativeURL.getLength() - 1 ] == '/' ) + sRelativeURL = sRelativeURL.copy( 0, sRelativeURL.getLength() - 1 ); + + // remove the last segment + const sal_Int32 nLastSep = sRelativeURL.lastIndexOf( '/' ); + sRelativeURL = sRelativeURL.copy( 0, nLastSep != -1 ? nLastSep : 0 ); + + ::rtl::OUStringBuffer aComposer; + aComposer.append( sRootURL ); + aComposer.append( sSeparatedExtensionId ); + aComposer.append( sRelativeURL ); + return aComposer.makeStringAndClear(); + } + break; + + default: + OSL_ENSURE( false, "Content::getParentURL: unhandled case!" ); + break; } - const ::rtl::OUString sParentURL( sURL.copy( 0, nCopyUpTo ) ); - return sParentURL; + return ::rtl::OUString(); } //------------------------------------------------------------------------------------------------------------------ diff --git a/ucb/source/ucp/ext/ucpext_content.hxx b/ucb/source/ucp/ext/ucpext_content.hxx index a9ee22ca8078..36380d8a7d68 100644 --- a/ucb/source/ucp/ext/ucpext_content.hxx +++ b/ucb/source/ucp/ext/ucpext_content.hxx @@ -135,10 +135,6 @@ namespace ucb { namespace ucp { namespace ext ); 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(); diff --git a/ucb/source/ucp/ext/ucpext_datasupplier.cxx b/ucb/source/ucp/ext/ucpext_datasupplier.cxx index dcc1c117befa..dfdd1df82fd6 100644 --- a/ucb/source/ucp/ext/ucpext_datasupplier.cxx +++ b/ucb/source/ucp/ext/ucpext_datasupplier.cxx @@ -167,7 +167,7 @@ namespace ucb { namespace ucp { namespace ext const ::rtl::OUString& rLocalId = (*pExtInfo)[0]; ResultListEntry aEntry; - aEntry.sId = lcl_compose( sContentIdentifier, Content::encodeIdentifier( rLocalId ) ); + aEntry.sId = ContentProvider::getRootURL() + Content::encodeIdentifier( rLocalId ) + ::rtl::OUString( sal_Unicode( '/' ) ); m_pImpl->m_aResults.push_back( aEntry ); } } @@ -327,7 +327,10 @@ namespace ucb { namespace ucp { namespace ext case E_ROOT: { const ::rtl::OUString& rId( m_pImpl->m_aResults[ i_nIndex ].sId ); - const ::rtl::OUString sTitle = Content::decodeIdentifier( rId.copy( rId.indexOf( '/' ) + 1 ) ); + 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; diff --git a/ucb/source/ucp/ext/ucpext_provider.cxx b/ucb/source/ucp/ext/ucpext_provider.cxx index b626999b66b5..0fbad1d8cf17 100644 --- a/ucb/source/ucp/ext/ucpext_provider.cxx +++ b/ucb/source/ucp/ext/ucpext_provider.cxx @@ -113,7 +113,7 @@ namespace ucb { namespace ucp { namespace ext //------------------------------------------------------------------------------------------------------------------ ::rtl::OUString ContentProvider::getRootURL() { - return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.extension:/" ) ); + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.extension://" ) ); } //------------------------------------------------------------------------------------------------------------------ @@ -123,19 +123,68 @@ namespace ucb { namespace ucp { namespace ext } //------------------------------------------------------------------------------------------------------------------ + namespace + { + void lcl_ensureAndTransfer( ::rtl::OUString& io_rIdentifierFragment, ::rtl::OUStringBuffer& o_rNormalization, const sal_Unicode i_nLeadingChar ) + { + if ( ( io_rIdentifierFragment.getLength() == 0 ) || ( io_rIdentifierFragment[0] != i_nLeadingChar ) ) + throw IllegalIdentifierException(); + io_rIdentifierFragment = io_rIdentifierFragment.copy( 1 ); + o_rNormalization.append( i_nLeadingChar ); + } + } + + //------------------------------------------------------------------------------------------------------------------ Reference< XContent > SAL_CALL ContentProvider::queryContent( const Reference< XContentIdentifier >& i_rIdentifier ) throw( IllegalIdentifierException, RuntimeException ) { // Check URL scheme... - const ::rtl::OUString aScheme( rtl::OUString::createFromAscii( "vnd.sun.star.extension" ) ); - if ( !i_rIdentifier->getContentProviderScheme().equalsIgnoreAsciiCase( aScheme ) ) + const ::rtl::OUString sScheme( rtl::OUString::createFromAscii( "vnd.sun.star.extension" ) ); + if ( !i_rIdentifier->getContentProviderScheme().equalsIgnoreAsciiCase( sScheme ) ) throw IllegalIdentifierException(); - // normalize the scheme + // normalize the identifier const ::rtl::OUString sIdentifier( i_rIdentifier->getContentIdentifier() ); + + // the scheme needs to be lower-case ::rtl::OUStringBuffer aComposer; - aComposer.append( sIdentifier.copy( 0, aScheme.getLength() ).toAsciiLowerCase() ); - aComposer.append( sIdentifier.copy( aScheme.getLength() ) ); + aComposer.append( sIdentifier.copy( 0, sScheme.getLength() ).toAsciiLowerCase() ); + + // one : is required after the scheme + ::rtl::OUString sRemaining( sIdentifier.copy( sScheme.getLength() ) ); + lcl_ensureAndTransfer( sRemaining, aComposer, ':' ); + + // and at least one / + lcl_ensureAndTransfer( sRemaining, aComposer, '/' ); + + // the normalized form requires one additional /, but we also accept identifiers which don't have it + if ( sRemaining.getLength() == 0 ) + { + // the root content is a special case, it requires /// + aComposer.appendAscii( "//" ); + } + else + { + if ( sRemaining[0] != '/' ) + { + aComposer.append( sal_Unicode( '/' ) ); + aComposer.append( sRemaining ); + } + else + { + lcl_ensureAndTransfer( sRemaining, aComposer, '/' ); + // by now, we moved "vnd.sun.star.extension://" from the URL to aComposer + if ( sRemaining.getLength() == 0 ) + { + // again, it's the root content, but one / is missing + aComposer.append( sal_Unicode( '/' ) ); + } + else + { + aComposer.append( sRemaining ); + } + } + } const Reference< XContentIdentifier > xNormalizedIdentifier( new ::ucbhelper::ContentIdentifier( m_xSMgr, aComposer.makeStringAndClear() ) ); ::osl::MutexGuard aGuard( m_aMutex ); |