1
0
Fork 0
libreoffice/xmlhelp/source/cxxhelp/provider/resultsetbase.cxx
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

485 lines
11 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#include <ucbhelper/contentidentifier.hxx>
#include <com/sun/star/sdbc/SQLException.hpp>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <ucbhelper/resultsetmetadata.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <utility>
#include "resultsetbase.hxx"
using namespace chelp;
using namespace com::sun::star;
ResultSetBase::ResultSetBase( uno::Reference< uno::XComponentContext > xContext,
uno::Reference< ucb::XContentProvider > xProvider,
const uno::Sequence< beans::Property >& seq )
: m_xContext(std::move( xContext )),
m_xProvider(std::move( xProvider )),
m_nRow( -1 ),
m_nWasNull( true ),
m_sProperty( seq )
{
}
ResultSetBase::~ResultSetBase()
{
}
// XInterface
void SAL_CALL
ResultSetBase::acquire()
noexcept
{
OWeakObject::acquire();
}
void SAL_CALL
ResultSetBase::release()
noexcept
{
OWeakObject::release();
}
uno::Any SAL_CALL
ResultSetBase::queryInterface( const uno::Type& rType )
{
uno::Any aRet = cppu::queryInterface( rType,
static_cast< lang::XComponent* >(this),
static_cast< sdbc::XRow* >(this),
static_cast< sdbc::XResultSet* >(this),
static_cast< sdbc::XResultSetMetaDataSupplier* >(this),
static_cast< beans::XPropertySet* >(this),
static_cast< ucb::XContentAccess* >(this) );
return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
}
// XComponent
void SAL_CALL
ResultSetBase::addEventListener(
const uno::Reference< lang::XEventListener >& Listener )
{
std::unique_lock aGuard( m_aMutex );
m_aDisposeEventListeners.addInterface( aGuard, Listener );
}
void SAL_CALL
ResultSetBase::removeEventListener(
const uno::Reference< lang::XEventListener >& Listener )
{
std::unique_lock aGuard( m_aMutex );
m_aDisposeEventListeners.removeInterface( aGuard, Listener );
}
void SAL_CALL
ResultSetBase::dispose()
{
std::unique_lock aGuard( m_aMutex );
lang::EventObject aEvt;
aEvt.Source = static_cast< lang::XComponent * >( this );
if ( m_aDisposeEventListeners.getLength(aGuard) )
{
m_aDisposeEventListeners.disposeAndClear( aGuard, aEvt );
}
if( m_aRowCountListeners.getLength(aGuard) )
{
m_aRowCountListeners.disposeAndClear( aGuard, aEvt );
}
if( m_aIsFinalListeners.getLength(aGuard) )
{
m_aIsFinalListeners.disposeAndClear( aGuard, aEvt );
}
}
// XResultSet
sal_Bool SAL_CALL
ResultSetBase::next()
{
m_nRow++;
return sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size();
}
sal_Bool SAL_CALL
ResultSetBase::isBeforeFirst()
{
return m_nRow == -1;
}
sal_Bool SAL_CALL
ResultSetBase::isAfterLast()
{
return sal::static_int_cast<sal_uInt32>( m_nRow ) >= m_aItems.size(); // Cannot happen, if m_aFolder.isOpen()
}
sal_Bool SAL_CALL
ResultSetBase::isFirst()
{
return m_nRow == 0;
}
sal_Bool SAL_CALL
ResultSetBase::isLast()
{
if( sal::static_int_cast<sal_uInt32>( m_nRow ) == m_aItems.size() - 1 )
return true;
else
return false;
}
void SAL_CALL
ResultSetBase::beforeFirst()
{
m_nRow = -1;
}
void SAL_CALL
ResultSetBase::afterLast()
{
m_nRow = m_aItems.size();
}
sal_Bool SAL_CALL
ResultSetBase::first()
{
m_nRow = -1;
return next();
}
sal_Bool SAL_CALL
ResultSetBase::last()
{
m_nRow = m_aItems.size() - 1;
return true;
}
sal_Int32 SAL_CALL
ResultSetBase::getRow()
{
// Test, whether behind last row
if( -1 == m_nRow || sal::static_int_cast<sal_uInt32>( m_nRow ) >= m_aItems.size() )
return 0;
else
return m_nRow+1;
}
sal_Bool SAL_CALL ResultSetBase::absolute( sal_Int32 row )
{
if( row >= 0 )
m_nRow = row - 1;
else
{
last();
m_nRow += ( row + 1 );
if( m_nRow < -1 )
m_nRow = -1;
}
return 0<= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size();
}
sal_Bool SAL_CALL
ResultSetBase::relative( sal_Int32 row )
{
if( isAfterLast() || isBeforeFirst() )
throw sdbc::SQLException();
if( row > 0 )
while( row-- )
next();
else if( row < 0 )
while( row++ && m_nRow > -1 )
previous();
return 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size();
}
sal_Bool SAL_CALL
ResultSetBase::previous()
{
if( sal::static_int_cast<sal_uInt32>( m_nRow ) > m_aItems.size() )
m_nRow = m_aItems.size(); // Correct Handling of afterLast
if( 0 <= m_nRow ) -- m_nRow;
return 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size();
}
void SAL_CALL
ResultSetBase::refreshRow()
{
}
sal_Bool SAL_CALL
ResultSetBase::rowUpdated()
{
return false;
}
sal_Bool SAL_CALL
ResultSetBase::rowInserted()
{
return false;
}
sal_Bool SAL_CALL
ResultSetBase::rowDeleted()
{
return false;
}
uno::Reference< uno::XInterface > SAL_CALL
ResultSetBase::getStatement()
{
return uno::Reference< uno::XInterface >();
}
// XCloseable
void SAL_CALL
ResultSetBase::close()
{
}
OUString SAL_CALL
ResultSetBase::queryContentIdentifierString()
{
if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() )
return m_aPath[m_nRow];
else
return OUString();
}
uno::Reference< ucb::XContentIdentifier > SAL_CALL
ResultSetBase::queryContentIdentifier()
{
if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() )
{
OUString url = queryContentIdentifierString();
if( ! m_aIdents[m_nRow].is() && !url.isEmpty() )
m_aIdents[m_nRow].set( new ::ucbhelper::ContentIdentifier( url ) );
return m_aIdents[m_nRow];
}
return uno::Reference< ucb::XContentIdentifier >();
}
uno::Reference< ucb::XContent > SAL_CALL
ResultSetBase::queryContent()
{
if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() )
return m_xProvider->queryContent( queryContentIdentifier() );
else
return uno::Reference< ucb::XContent >();
}
namespace {
class XPropertySetInfoImpl
: public cppu::OWeakObject,
public beans::XPropertySetInfo
{
public:
explicit XPropertySetInfoImpl( const uno::Sequence< beans::Property >& aSeq )
: m_aSeq( aSeq )
{
}
void SAL_CALL acquire()
noexcept override
{
OWeakObject::acquire();
}
void SAL_CALL release()
noexcept override
{
OWeakObject::release();
}
uno::Any SAL_CALL queryInterface( const uno::Type& rType ) override
{
uno::Any aRet = cppu::queryInterface( rType,
static_cast< beans::XPropertySetInfo* >(this) );
return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
}
uno::Sequence< beans::Property > SAL_CALL getProperties() override
{
return m_aSeq;
}
beans::Property SAL_CALL getPropertyByName( const OUString& aName ) override
{
auto pProp = std::find_if(std::cbegin(m_aSeq), std::cend(m_aSeq),
[&aName](const beans::Property& rProp) { return aName == rProp.Name; });
if (pProp != std::cend(m_aSeq))
return *pProp;
throw beans::UnknownPropertyException(aName);
}
sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override
{
return std::any_of(std::cbegin(m_aSeq), std::cend(m_aSeq),
[&Name](const beans::Property& rProp) { return Name == rProp.Name; });
}
private:
uno::Sequence< beans::Property > m_aSeq;
};
}
// XPropertySet
uno::Reference< beans::XPropertySetInfo > SAL_CALL
ResultSetBase::getPropertySetInfo()
{
uno::Sequence< beans::Property > seq
{
{ u"RowCount"_ustr, -1, cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY },
{ u"IsRowCountFinal"_ustr, -1, cppu::UnoType<sal_Bool>::get(), beans::PropertyAttribute::READONLY }
};
//t
return uno::Reference< beans::XPropertySetInfo > ( new XPropertySetInfoImpl( seq ) );
}
void SAL_CALL ResultSetBase::setPropertyValue(
const OUString& aPropertyName, const uno::Any& )
{
if( aPropertyName == "IsRowCountFinal" ||
aPropertyName == "RowCount" )
return;
throw beans::UnknownPropertyException(aPropertyName);
}
uno::Any SAL_CALL ResultSetBase::getPropertyValue(
const OUString& PropertyName )
{
if( PropertyName == "IsRowCountFinal" )
{
return uno::Any(true);
}
else if ( PropertyName == "RowCount" )
{
sal_Int32 count = m_aItems.size();
return uno::Any(count);
}
else
throw beans::UnknownPropertyException(PropertyName);
}
void SAL_CALL ResultSetBase::addPropertyChangeListener(
const OUString& aPropertyName,
const uno::Reference< beans::XPropertyChangeListener >& xListener )
{
if( aPropertyName == "IsRowCountFinal" )
{
std::unique_lock aGuard( m_aMutex );
m_aIsFinalListeners.addInterface( aGuard, xListener );
}
else if ( aPropertyName == "RowCount" )
{
std::unique_lock aGuard( m_aMutex );
m_aRowCountListeners.addInterface( aGuard, xListener );
}
else
throw beans::UnknownPropertyException(aPropertyName);
}
void SAL_CALL ResultSetBase::removePropertyChangeListener(
const OUString& aPropertyName,
const uno::Reference< beans::XPropertyChangeListener >& aListener )
{
if( aPropertyName == "IsRowCountFinal" )
{
std::unique_lock aGuard( m_aMutex );
m_aIsFinalListeners.removeInterface( aGuard, aListener );
}
else if ( aPropertyName == "RowCount" )
{
std::unique_lock aGuard( m_aMutex );
m_aRowCountListeners.removeInterface( aGuard, aListener );
}
else
throw beans::UnknownPropertyException(aPropertyName);
}
void SAL_CALL ResultSetBase::addVetoableChangeListener(
const OUString&,
const uno::Reference< beans::XVetoableChangeListener >& )
{}
void SAL_CALL ResultSetBase::removeVetoableChangeListener(
const OUString&,
const uno::Reference< beans::XVetoableChangeListener >& )
{}
// XResultSetMetaDataSupplier
uno::Reference< sdbc::XResultSetMetaData > SAL_CALL
ResultSetBase::getMetaData()
{
return new ::ucbhelper::ResultSetMetaData( m_xContext, m_sProperty );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */