1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <ucbhelper/contentidentifier.hxx>
21 #include <com/sun/star/sdbc/SQLException.hpp>
22 #include <com/sun/star/uno/Reference.h>
23 #include <com/sun/star/beans/PropertyAttribute.hpp>
24 #include <ucbhelper/resultsetmetadata.hxx>
25 #include <cppuhelper/queryinterface.hxx>
28 #include "resultsetbase.hxx"
30 using namespace chelp
;
31 using namespace com::sun::star
;
33 ResultSetBase::ResultSetBase( uno::Reference
< uno::XComponentContext
> xContext
,
34 uno::Reference
< ucb::XContentProvider
> xProvider
,
35 const uno::Sequence
< beans::Property
>& seq
)
36 : m_xContext(std::move( xContext
)),
37 m_xProvider(std::move( xProvider
)),
44 ResultSetBase::~ResultSetBase()
52 ResultSetBase::acquire()
55 OWeakObject::acquire();
60 ResultSetBase::release()
63 OWeakObject::release();
68 ResultSetBase::queryInterface( const uno::Type
& rType
)
70 uno::Any aRet
= cppu::queryInterface( rType
,
71 static_cast< lang::XComponent
* >(this),
72 static_cast< sdbc::XRow
* >(this),
73 static_cast< sdbc::XResultSet
* >(this),
74 static_cast< sdbc::XResultSetMetaDataSupplier
* >(this),
75 static_cast< beans::XPropertySet
* >(this),
76 static_cast< ucb::XContentAccess
* >(this) );
77 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
85 ResultSetBase::addEventListener(
86 const uno::Reference
< lang::XEventListener
>& Listener
)
88 std::unique_lock
aGuard( m_aMutex
);
89 m_aDisposeEventListeners
.addInterface( aGuard
, Listener
);
94 ResultSetBase::removeEventListener(
95 const uno::Reference
< lang::XEventListener
>& Listener
)
97 std::unique_lock
aGuard( m_aMutex
);
98 m_aDisposeEventListeners
.removeInterface( aGuard
, Listener
);
103 ResultSetBase::dispose()
105 std::unique_lock
aGuard( m_aMutex
);
107 lang::EventObject aEvt
;
108 aEvt
.Source
= static_cast< lang::XComponent
* >( this );
110 if ( m_aDisposeEventListeners
.getLength(aGuard
) )
112 m_aDisposeEventListeners
.disposeAndClear( aGuard
, aEvt
);
114 if( m_aRowCountListeners
.getLength(aGuard
) )
116 m_aRowCountListeners
.disposeAndClear( aGuard
, aEvt
);
118 if( m_aIsFinalListeners
.getLength(aGuard
) )
120 m_aIsFinalListeners
.disposeAndClear( aGuard
, aEvt
);
128 ResultSetBase::next()
131 return sal::static_int_cast
<sal_uInt32
>( m_nRow
) < m_aItems
.size();
136 ResultSetBase::isBeforeFirst()
143 ResultSetBase::isAfterLast()
145 return sal::static_int_cast
<sal_uInt32
>( m_nRow
) >= m_aItems
.size(); // Cannot happen, if m_aFolder.isOpen()
150 ResultSetBase::isFirst()
157 ResultSetBase::isLast()
159 if( sal::static_int_cast
<sal_uInt32
>( m_nRow
) == m_aItems
.size() - 1 )
167 ResultSetBase::beforeFirst()
174 ResultSetBase::afterLast()
176 m_nRow
= m_aItems
.size();
181 ResultSetBase::first()
189 ResultSetBase::last()
191 m_nRow
= m_aItems
.size() - 1;
197 ResultSetBase::getRow()
199 // Test, whether behind last row
200 if( -1 == m_nRow
|| sal::static_int_cast
<sal_uInt32
>( m_nRow
) >= m_aItems
.size() )
207 sal_Bool SAL_CALL
ResultSetBase::absolute( sal_Int32 row
)
214 m_nRow
+= ( row
+ 1 );
219 return 0<= m_nRow
&& sal::static_int_cast
<sal_uInt32
>( m_nRow
) < m_aItems
.size();
224 ResultSetBase::relative( sal_Int32 row
)
226 if( isAfterLast() || isBeforeFirst() )
227 throw sdbc::SQLException();
233 while( row
++ && m_nRow
> -1 )
236 return 0 <= m_nRow
&& sal::static_int_cast
<sal_uInt32
>( m_nRow
) < m_aItems
.size();
241 ResultSetBase::previous()
243 if( sal::static_int_cast
<sal_uInt32
>( m_nRow
) > m_aItems
.size() )
244 m_nRow
= m_aItems
.size(); // Correct Handling of afterLast
245 if( 0 <= m_nRow
) -- m_nRow
;
247 return 0 <= m_nRow
&& sal::static_int_cast
<sal_uInt32
>( m_nRow
) < m_aItems
.size();
252 ResultSetBase::refreshRow()
258 ResultSetBase::rowUpdated()
264 ResultSetBase::rowInserted()
270 ResultSetBase::rowDeleted()
276 uno::Reference
< uno::XInterface
> SAL_CALL
277 ResultSetBase::getStatement()
279 return uno::Reference
< uno::XInterface
>();
286 ResultSetBase::close()
292 ResultSetBase::queryContentIdentifierString()
294 if( 0 <= m_nRow
&& sal::static_int_cast
<sal_uInt32
>( m_nRow
) < m_aItems
.size() )
295 return m_aPath
[m_nRow
];
301 uno::Reference
< ucb::XContentIdentifier
> SAL_CALL
302 ResultSetBase::queryContentIdentifier()
304 if( 0 <= m_nRow
&& sal::static_int_cast
<sal_uInt32
>( m_nRow
) < m_aItems
.size() )
306 OUString url
= queryContentIdentifierString();
307 if( ! m_aIdents
[m_nRow
].is() && !url
.isEmpty() )
308 m_aIdents
[m_nRow
].set( new ::ucbhelper::ContentIdentifier( url
) );
309 return m_aIdents
[m_nRow
];
312 return uno::Reference
< ucb::XContentIdentifier
>();
316 uno::Reference
< ucb::XContent
> SAL_CALL
317 ResultSetBase::queryContent()
319 if( 0 <= m_nRow
&& sal::static_int_cast
<sal_uInt32
>( m_nRow
) < m_aItems
.size() )
320 return m_xProvider
->queryContent( queryContentIdentifier() );
322 return uno::Reference
< ucb::XContent
>();
327 class XPropertySetInfoImpl
328 : public cppu::OWeakObject
,
329 public beans::XPropertySetInfo
333 explicit XPropertySetInfoImpl( const uno::Sequence
< beans::Property
>& aSeq
)
338 void SAL_CALL
acquire()
341 OWeakObject::acquire();
345 void SAL_CALL
release()
348 OWeakObject::release();
351 uno::Any SAL_CALL
queryInterface( const uno::Type
& rType
) override
353 uno::Any aRet
= cppu::queryInterface( rType
,
354 static_cast< beans::XPropertySetInfo
* >(this) );
355 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
358 uno::Sequence
< beans::Property
> SAL_CALL
getProperties() override
363 beans::Property SAL_CALL
getPropertyByName( const OUString
& aName
) override
365 auto pProp
= std::find_if(std::cbegin(m_aSeq
), std::cend(m_aSeq
),
366 [&aName
](const beans::Property
& rProp
) { return aName
== rProp
.Name
; });
367 if (pProp
!= std::cend(m_aSeq
))
369 throw beans::UnknownPropertyException(aName
);
372 sal_Bool SAL_CALL
hasPropertyByName( const OUString
& Name
) override
374 return std::any_of(std::cbegin(m_aSeq
), std::cend(m_aSeq
),
375 [&Name
](const beans::Property
& rProp
) { return Name
== rProp
.Name
; });
380 uno::Sequence
< beans::Property
> m_aSeq
;
386 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
387 ResultSetBase::getPropertySetInfo()
389 uno::Sequence
< beans::Property
> seq
391 { u
"RowCount"_ustr
, -1, cppu::UnoType
<sal_Int32
>::get(), beans::PropertyAttribute::READONLY
},
392 { u
"IsRowCountFinal"_ustr
, -1, cppu::UnoType
<sal_Bool
>::get(), beans::PropertyAttribute::READONLY
}
396 return uno::Reference
< beans::XPropertySetInfo
> ( new XPropertySetInfoImpl( seq
) );
400 void SAL_CALL
ResultSetBase::setPropertyValue(
401 const OUString
& aPropertyName
, const uno::Any
& )
403 if( aPropertyName
== "IsRowCountFinal" ||
404 aPropertyName
== "RowCount" )
407 throw beans::UnknownPropertyException(aPropertyName
);
411 uno::Any SAL_CALL
ResultSetBase::getPropertyValue(
412 const OUString
& PropertyName
)
414 if( PropertyName
== "IsRowCountFinal" )
416 return uno::Any(true);
418 else if ( PropertyName
== "RowCount" )
420 sal_Int32 count
= m_aItems
.size();
421 return uno::Any(count
);
424 throw beans::UnknownPropertyException(PropertyName
);
428 void SAL_CALL
ResultSetBase::addPropertyChangeListener(
429 const OUString
& aPropertyName
,
430 const uno::Reference
< beans::XPropertyChangeListener
>& xListener
)
432 if( aPropertyName
== "IsRowCountFinal" )
434 std::unique_lock
aGuard( m_aMutex
);
435 m_aIsFinalListeners
.addInterface( aGuard
, xListener
);
437 else if ( aPropertyName
== "RowCount" )
439 std::unique_lock
aGuard( m_aMutex
);
440 m_aRowCountListeners
.addInterface( aGuard
, xListener
);
443 throw beans::UnknownPropertyException(aPropertyName
);
447 void SAL_CALL
ResultSetBase::removePropertyChangeListener(
448 const OUString
& aPropertyName
,
449 const uno::Reference
< beans::XPropertyChangeListener
>& aListener
)
451 if( aPropertyName
== "IsRowCountFinal" )
453 std::unique_lock
aGuard( m_aMutex
);
454 m_aIsFinalListeners
.removeInterface( aGuard
, aListener
);
456 else if ( aPropertyName
== "RowCount" )
458 std::unique_lock
aGuard( m_aMutex
);
459 m_aRowCountListeners
.removeInterface( aGuard
, aListener
);
462 throw beans::UnknownPropertyException(aPropertyName
);
466 void SAL_CALL
ResultSetBase::addVetoableChangeListener(
468 const uno::Reference
< beans::XVetoableChangeListener
>& )
472 void SAL_CALL
ResultSetBase::removeVetoableChangeListener(
474 const uno::Reference
< beans::XVetoableChangeListener
>& )
478 // XResultSetMetaDataSupplier
479 uno::Reference
< sdbc::XResultSetMetaData
> SAL_CALL
480 ResultSetBase::getMetaData()
482 return new ::ucbhelper::ResultSetMetaData( m_xContext
, m_sProperty
);
485 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */