blob: b25582c49a6641edc69f5419631facc53fe4248a [file] [log] [blame]
/**************************************************************
*
* 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
//......................................................................................................................