summaryrefslogtreecommitdiff
path: root/ucb/source/sorter
diff options
context:
space:
mode:
Diffstat (limited to 'ucb/source/sorter')
-rw-r--r--ucb/source/sorter/makefile.mk71
-rw-r--r--ucb/source/sorter/sortdynres.cxx628
-rw-r--r--ucb/source/sorter/sortdynres.hxx257
-rw-r--r--ucb/source/sorter/sortmain.cxx75
-rw-r--r--ucb/source/sorter/sortresult.cxx2070
-rw-r--r--ucb/source/sorter/sortresult.hxx455
-rw-r--r--ucb/source/sorter/srtrs.xml66
-rw-r--r--ucb/source/sorter/srtrs1.component34
8 files changed, 3656 insertions, 0 deletions
diff --git a/ucb/source/sorter/makefile.mk b/ucb/source/sorter/makefile.mk
new file mode 100644
index 000000000000..008e39b4bce3
--- /dev/null
+++ b/ucb/source/sorter/makefile.mk
@@ -0,0 +1,71 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=ucb
+TARGET=srtrs
+ENABLE_EXCEPTIONS=TRUE
+
+# Version
+UCB_MAJOR=1
+
+.INCLUDE: settings.mk
+.IF "$(L10N_framework)"==""
+
+SLOFILES=\
+ $(SLO)$/sortdynres.obj \
+ $(SLO)$/sortresult.obj \
+ $(SLO)$/sortmain.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+SHL1TARGET=$(TARGET)$(UCB_MAJOR)
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1LIBS=$(LIB1TARGET)
+SHL1IMPLIB=i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+
+DEF1NAME=$(SHL1TARGET)
+.ENDIF # L10N_framework
+
+.INCLUDE: target.mk
+
+
+ALLTAR : $(MISC)/srtrs1.component
+
+$(MISC)/srtrs1.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ srtrs1.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt srtrs1.component
diff --git a/ucb/source/sorter/sortdynres.cxx b/ucb/source/sorter/sortdynres.cxx
new file mode 100644
index 000000000000..2fc38ee46a42
--- /dev/null
+++ b/ucb/source/sorter/sortdynres.cxx
@@ -0,0 +1,628 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <vector>
+#include <sortdynres.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/ucb/ContentResultSetCapability.hpp>
+#include <com/sun/star/ucb/ListActionType.hpp>
+#include <com/sun/star/ucb/WelcomeDynamicResultSetStruct.hpp>
+#include <com/sun/star/ucb/XCachedDynamicResultSetStubFactory.hpp>
+#include <com/sun/star/ucb/XSourceInitialization.hpp>
+
+//-----------------------------------------------------------------------------
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace cppu;
+using namespace rtl;
+
+//=========================================================================
+
+// The mutex to synchronize access to containers.
+static osl::Mutex& getContainerMutex()
+{
+ static osl::Mutex* pMutex = NULL;
+ if( !pMutex )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pMutex )
+ {
+ static osl::Mutex aMutex;
+ pMutex = &aMutex;
+ }
+ }
+
+ return *pMutex;
+}
+
+//=========================================================================
+//
+// SortedDynamicResultSet
+//
+//=========================================================================
+
+SortedDynamicResultSet::SortedDynamicResultSet(
+ const Reference < XDynamicResultSet > &xOriginal,
+ const Sequence < NumberedSortingInfo > &aOptions,
+ const Reference < XAnyCompareFactory > &xCompFac,
+ const Reference < XMultiServiceFactory > &xSMgr )
+{
+ mpDisposeEventListeners = NULL;
+ mpOwnListener = new SortedDynamicResultSetListener( this );
+
+ mxOwnListener = Reference< XDynamicResultSetListener >( mpOwnListener );
+
+ mxOriginal = xOriginal;
+ maOptions = aOptions;
+ mxCompFac = xCompFac;
+ mxSMgr = xSMgr;
+
+ mpOne = NULL;
+ mpTwo = NULL;
+
+ mbGotWelcome = sal_False;
+ mbUseOne = sal_True;
+ mbStatic = sal_False;
+}
+
+//--------------------------------------------------------------------------
+SortedDynamicResultSet::~SortedDynamicResultSet()
+{
+ mpOwnListener->impl_OwnerDies();
+ mxOwnListener.clear();
+
+ delete mpDisposeEventListeners;
+
+ mxOne.clear();
+ mxTwo.clear();
+ mxOriginal.clear();
+
+ mpOne = NULL;
+ mpTwo = NULL;
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+
+XINTERFACE_IMPL_4( SortedDynamicResultSet,
+ XTypeProvider,
+ XServiceInfo,
+ XComponent, /* base class of XDynamicResultSet */
+ XDynamicResultSet );
+
+//--------------------------------------------------------------------------
+// XTypeProvider methods.
+//--------------------------------------------------------------------------
+
+XTYPEPROVIDER_IMPL_3( SortedDynamicResultSet,
+ XTypeProvider,
+ XServiceInfo,
+ XDynamicResultSet );
+
+//--------------------------------------------------------------------------
+// XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_NOFACTORY_IMPL_1( SortedDynamicResultSet,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.SortedDynamicResultSet" ),
+ OUString::createFromAscii(
+ DYNAMIC_RESULTSET_SERVICE_NAME ) );
+
+//--------------------------------------------------------------------------
+// XComponent methods.
+//--------------------------------------------------------------------------
+void SAL_CALL SortedDynamicResultSet::dispose()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XComponent * >( this );
+ mpDisposeEventListeners->disposeAndClear( aEvt );
+ }
+
+ mxOne.clear();
+ mxTwo.clear();
+ mxOriginal.clear();
+
+ mpOne = NULL;
+ mpTwo = NULL;
+ mbUseOne = sal_True;
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedDynamicResultSet::addEventListener(
+ const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpDisposeEventListeners )
+ mpDisposeEventListeners =
+ new OInterfaceContainerHelper( getContainerMutex() );
+
+ mpDisposeEventListeners->addInterface( Listener );
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedDynamicResultSet::removeEventListener(
+ const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpDisposeEventListeners )
+ mpDisposeEventListeners->removeInterface( Listener );
+}
+
+//--------------------------------------------------------------------------
+// XDynamicResultSet methods.
+// ------------------------------------------------------------------------------
+Reference< XResultSet > SAL_CALL
+SortedDynamicResultSet::getStaticResultSet()
+ throw( ListenerAlreadySetException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mxListener.is() )
+ throw ListenerAlreadySetException();
+
+ mbStatic = sal_True;
+
+ if ( mxOriginal.is() )
+ {
+ mpOne = new SortedResultSet( mxOriginal->getStaticResultSet() );
+ mxOne = mpOne;
+ mpOne->Initialize( maOptions, mxCompFac );
+ }
+
+ return mxOne;
+}
+
+// ------------------------------------------------------------------------------
+void SAL_CALL
+SortedDynamicResultSet::setListener( const Reference< XDynamicResultSetListener >& Listener )
+ throw( ListenerAlreadySetException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mxListener.is() )
+ throw ListenerAlreadySetException();
+
+ addEventListener( Reference< XEventListener >::query( Listener ) );
+
+ mxListener = Listener;
+
+ if ( mxOriginal.is() )
+ mxOriginal->setListener( mxOwnListener );
+}
+
+// ------------------------------------------------------------------------------
+void SAL_CALL
+SortedDynamicResultSet::connectToCache(
+ const Reference< XDynamicResultSet > & xCache )
+ throw( ListenerAlreadySetException,
+ AlreadyInitializedException,
+ ServiceNotFoundException,
+ RuntimeException )
+{
+ if( mxListener.is() )
+ throw ListenerAlreadySetException();
+
+ if( mbStatic )
+ throw ListenerAlreadySetException();
+
+ Reference< XSourceInitialization > xTarget( xCache, UNO_QUERY );
+ if( xTarget.is() && mxSMgr.is() )
+ {
+ Reference< XCachedDynamicResultSetStubFactory > xStubFactory;
+ try
+ {
+ xStubFactory = Reference< XCachedDynamicResultSetStubFactory >(
+ mxSMgr->createInstance(
+ OUString::createFromAscii(
+ "com.sun.star.ucb.CachedDynamicResultSetStubFactory" ) ),
+ UNO_QUERY );
+ }
+ catch ( Exception const & )
+ {
+ }
+
+ if( xStubFactory.is() )
+ {
+ xStubFactory->connectToCache(
+ this, xCache, Sequence< NumberedSortingInfo > (), NULL );
+ return;
+ }
+ }
+ throw ServiceNotFoundException();
+}
+
+// ------------------------------------------------------------------------------
+sal_Int16 SAL_CALL
+SortedDynamicResultSet::getCapabilities()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ sal_Int16 nCaps = 0;
+
+ if ( mxOriginal.is() )
+ nCaps = mxOriginal->getCapabilities();
+
+ nCaps |= ContentResultSetCapability::SORTED;
+
+ return nCaps;
+}
+
+//--------------------------------------------------------------------------
+// XDynamicResultSetListener methods.
+// ------------------------------------------------------------------------------
+
+/** In the first notify-call the listener gets the two
+ <type>XResultSet</type>s and has to hold them. The <type>XResultSet</type>s
+ are implementations of the service <type>ContentResultSet</type>.
+
+ <p>The notified new <type>XResultSet</type> will stay valid after returning
+ notification. The old one will become invalid after returning notification.
+
+ <p>While in notify-call the listener is allowed to read old and new version,
+ except in the first call, where only the new Resultset is valid.
+
+ <p>The Listener is allowed to blockade this call, until he really want to go
+ to the new version. The only situation, where the listener has to return the
+ update call at once is, while he disposes his broadcaster or while he is
+ removing himsef as listener (otherwise you deadlock)!!!
+*/
+void SAL_CALL
+SortedDynamicResultSet::impl_notify( const ListEvent& Changes )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ sal_Bool bHasNew = sal_False;
+ sal_Bool bHasModified = sal_False;
+
+ SortedResultSet *pCurSet = NULL;
+
+ // mxNew und mxOld vertauschen und anschliessend die Tabellen von Old
+ // nach New kopieren
+ if ( mbGotWelcome )
+ {
+ if ( mbUseOne )
+ {
+ mbUseOne = sal_False;
+ mpTwo->CopyData( mpOne );
+ pCurSet = mpTwo;
+ }
+ else
+ {
+ mbUseOne = sal_True;
+ mpOne->CopyData( mpTwo );
+ pCurSet = mpOne;
+ }
+ }
+
+ Any aRet;
+
+ try {
+ aRet = pCurSet->getPropertyValue( OUString::createFromAscii( "IsRowCountFinal" ) );
+ }
+ catch ( UnknownPropertyException ) {}
+ catch ( WrappedTargetException ) {}
+
+ long nOldCount = pCurSet->GetCount();
+ sal_Bool bWasFinal = false;
+
+ aRet >>= bWasFinal;
+
+ // handle the actions in the list
+ for ( long i=0; i<Changes.Changes.getLength(); i++ )
+ {
+ const ListAction aAction = Changes.Changes[i];
+ switch ( aAction.ListActionType )
+ {
+ case ListActionType::WELCOME:
+ {
+ WelcomeDynamicResultSetStruct aWelcome;
+ if ( aAction.ActionInfo >>= aWelcome )
+ {
+ mpTwo = new SortedResultSet( aWelcome.Old );
+ mxTwo = mpTwo;
+ mpOne = new SortedResultSet( aWelcome.New );
+ mxOne = mpOne;
+ mpOne->Initialize( maOptions, mxCompFac );
+ mbGotWelcome = sal_True;
+ mbUseOne = sal_True;
+ pCurSet = mpOne;
+
+ aWelcome.Old = mxTwo;
+ aWelcome.New = mxOne;
+
+ ListAction *pWelcomeAction = new ListAction;
+ pWelcomeAction->ActionInfo <<= aWelcome;
+ pWelcomeAction->Position = 0;
+ pWelcomeAction->Count = 0;
+ pWelcomeAction->ListActionType = ListActionType::WELCOME;
+
+ maActions.Insert( pWelcomeAction );
+ }
+ else
+ {
+ // throw RuntimeException();
+ }
+ break;
+ }
+ case ListActionType::INSERTED:
+ {
+ pCurSet->InsertNew( aAction.Position, aAction.Count );
+ bHasNew = sal_True;
+ break;
+ }
+ case ListActionType::REMOVED:
+ {
+ pCurSet->Remove( aAction.Position,
+ aAction.Count,
+ &maActions );
+ break;
+ }
+ case ListActionType::MOVED:
+ {
+ long nOffset = 0;
+ if ( aAction.ActionInfo >>= nOffset )
+ {
+ pCurSet->Move( aAction.Position,
+ aAction.Count,
+ nOffset );
+ }
+ break;
+ }
+ case ListActionType::PROPERTIES_CHANGED:
+ {
+ pCurSet->SetChanged( aAction.Position, aAction.Count );
+ bHasModified = sal_True;
+ break;
+ }
+ default: break;
+ }
+ }
+
+ if ( bHasModified )
+ pCurSet->ResortModified( &maActions );
+
+ if ( bHasNew )
+ pCurSet->ResortNew( &maActions );
+
+ // send the new actions with a notify to the listeners
+ SendNotify();
+
+ // check for propertyChangeEvents
+ pCurSet->CheckProperties( nOldCount, bWasFinal );
+}
+
+//-----------------------------------------------------------------
+// XEventListener
+//-----------------------------------------------------------------
+void SAL_CALL
+SortedDynamicResultSet::impl_disposing( const EventObject& )
+ throw( RuntimeException )
+{
+ mxListener.clear();
+ mxOriginal.clear();
+}
+
+// ------------------------------------------------------------------------------
+// private methods
+// ------------------------------------------------------------------------------
+void SortedDynamicResultSet::SendNotify()
+{
+ long nCount = maActions.Count();
+
+ if ( nCount && mxListener.is() )
+ {
+ Sequence< ListAction > aActionList( maActions.Count() );
+ ListAction *pActionList = aActionList.getArray();
+
+ for ( long i=0; i<nCount; i++ )
+ {
+ pActionList[ i ] = *(maActions.GetAction( i ));
+ }
+
+ ListEvent aNewEvent;
+ aNewEvent.Changes = aActionList;
+
+ mxListener->notify( aNewEvent );
+ }
+
+ // clean up
+ maActions.Clear();
+}
+
+//=========================================================================
+//
+// SortedDynamicResultSetFactory
+//
+//=========================================================================
+SortedDynamicResultSetFactory::SortedDynamicResultSetFactory(
+ const Reference< XMultiServiceFactory > & rSMgr )
+{
+ mxSMgr = rSMgr;
+}
+
+//--------------------------------------------------------------------------
+SortedDynamicResultSetFactory::~SortedDynamicResultSetFactory()
+{
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+
+XINTERFACE_IMPL_3( SortedDynamicResultSetFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XSortedDynamicResultSetFactory );
+
+//--------------------------------------------------------------------------
+// XTypeProvider methods.
+//--------------------------------------------------------------------------
+
+XTYPEPROVIDER_IMPL_3( SortedDynamicResultSetFactory,
+ XTypeProvider,
+ XServiceInfo,
+ XSortedDynamicResultSetFactory );
+
+//--------------------------------------------------------------------------
+// XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_IMPL_1( SortedDynamicResultSetFactory,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.SortedDynamicResultSetFactory" ),
+ OUString::createFromAscii(
+ DYNAMIC_RESULTSET_FACTORY_NAME ) );
+
+//--------------------------------------------------------------------------
+// Service factory implementation.
+//--------------------------------------------------------------------------
+
+ONE_INSTANCE_SERVICE_FACTORY_IMPL( SortedDynamicResultSetFactory );
+
+//--------------------------------------------------------------------------
+// SortedDynamicResultSetFactory methods.
+//--------------------------------------------------------------------------
+Reference< XDynamicResultSet > SAL_CALL
+SortedDynamicResultSetFactory::createSortedDynamicResultSet(
+ const Reference< XDynamicResultSet > & Source,
+ const Sequence< NumberedSortingInfo > & Info,
+ const Reference< XAnyCompareFactory > & CompareFactory )
+ throw( RuntimeException )
+{
+ Reference< XDynamicResultSet > xRet;
+ xRet = new SortedDynamicResultSet( Source, Info, CompareFactory, mxSMgr );
+ return xRet;
+}
+
+//=========================================================================
+//
+// EventList
+//
+//=========================================================================
+
+void EventList::Clear()
+{
+ for ( std::deque< LISTACTION* >::size_type i = 0;
+ i < maData.size(); ++i )
+ {
+ delete maData[i];
+ }
+
+ maData.clear();
+}
+
+//--------------------------------------------------------------------------
+void EventList::AddEvent( long nType, long nPos, long nCount )
+{
+ ListAction *pAction = new ListAction;
+ pAction->Position = nPos;
+ pAction->Count = nCount;
+ pAction->ListActionType = nType;
+
+ Insert( pAction );
+}
+
+//=================================================================
+//
+// SortedDynamicResultSetListener
+//
+//=================================================================
+
+SortedDynamicResultSetListener::SortedDynamicResultSetListener(
+ SortedDynamicResultSet *mOwner )
+{
+ mpOwner = mOwner;
+}
+
+//-----------------------------------------------------------------
+SortedDynamicResultSetListener::~SortedDynamicResultSetListener()
+{
+}
+
+//-----------------------------------------------------------------
+// XInterface methods.
+//-----------------------------------------------------------------
+
+XINTERFACE_IMPL_2( SortedDynamicResultSetListener,
+ XEventListener, /* base class of XDynamicResultSetListener */
+ XDynamicResultSetListener );
+
+//-----------------------------------------------------------------
+// XEventListener ( base of XDynamicResultSetListener )
+//-----------------------------------------------------------------
+void SAL_CALL
+SortedDynamicResultSetListener::disposing( const EventObject& Source )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpOwner )
+ mpOwner->impl_disposing( Source );
+}
+
+//-----------------------------------------------------------------
+// XDynamicResultSetListener
+//-----------------------------------------------------------------
+void SAL_CALL
+SortedDynamicResultSetListener::notify( const ListEvent& Changes )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpOwner )
+ mpOwner->impl_notify( Changes );
+}
+
+//-----------------------------------------------------------------
+// own methods:
+//-----------------------------------------------------------------
+void SAL_CALL
+SortedDynamicResultSetListener::impl_OwnerDies()
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ mpOwner = NULL;
+}
+
diff --git a/ucb/source/sorter/sortdynres.hxx b/ucb/source/sorter/sortdynres.hxx
new file mode 100644
index 000000000000..fe026d40a3f7
--- /dev/null
+++ b/ucb/source/sorter/sortdynres.hxx
@@ -0,0 +1,257 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SORTDYNRES_HXX
+#define _SORTDYNRES_HXX
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/ucb/XDynamicResultSetListener.hpp>
+#include <com/sun/star/ucb/ListenerAlreadySetException.hpp>
+#include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
+#include <cppuhelper/weak.hxx>
+#include <osl/mutex.hxx>
+#include <ucbhelper/macros.hxx>
+#include "sortresult.hxx"
+
+namespace cppu {
+ class OInterfaceContainerHelper;
+}
+
+//-----------------------------------------------------------------------------
+
+#define NUMBERED_SORTINGINFO com::sun::star::ucb::NumberedSortingInfo
+#define RUNTIMEEXCEPTION com::sun::star::uno::RuntimeException
+#define REFERENCE com::sun::star::uno::Reference
+#define SEQUENCE com::sun::star::uno::Sequence
+#define EVENTOBJECT com::sun::star::lang::EventObject
+#define XEVENTLISTENER com::sun::star::lang::XEventListener
+#define XMULTISERVICEFACTORY com::sun::star::lang::XMultiServiceFactory
+#define XRESULTSET com::sun::star::sdbc::XResultSet
+#define SQLEXCEPTION com::sun::star::sdbc::SQLException
+#define XANYCOMPAREFACTORY com::sun::star::ucb::XAnyCompareFactory
+#define XDYNAMICRESULTSET com::sun::star::ucb::XDynamicResultSet
+#define XDYNAMICRESULTSETLISTENER com::sun::star::ucb::XDynamicResultSetListener
+#define LISTENERALREADYSETEXCEPTION com::sun::star::ucb::ListenerAlreadySetException
+
+#define DYNAMIC_RESULTSET_SERVICE_NAME "com.sun.star.ucb.SortedDynamicResultSet"
+#define DYNAMIC_RESULTSET_FACTORY_NAME "com.sun.star.ucb.SortedDynamicResultSetFactory"
+
+//-----------------------------------------------------------------------------
+class SortedDynamicResultSetListener;
+
+class SortedDynamicResultSet:
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::ucb::XDynamicResultSet
+{
+ cppu::OInterfaceContainerHelper *mpDisposeEventListeners;
+
+ REFERENCE < XDYNAMICRESULTSETLISTENER > mxListener;
+ REFERENCE < XDYNAMICRESULTSETLISTENER > mxOwnListener;
+
+ REFERENCE < XRESULTSET > mxOne;
+ REFERENCE < XRESULTSET > mxTwo;
+ REFERENCE < XDYNAMICRESULTSET > mxOriginal;
+ SEQUENCE < NUMBERED_SORTINGINFO > maOptions;
+ REFERENCE < XANYCOMPAREFACTORY > mxCompFac;
+ REFERENCE < XMULTISERVICEFACTORY > mxSMgr;
+
+ SortedResultSet* mpOne;
+ SortedResultSet* mpTwo;
+ SortedDynamicResultSetListener* mpOwnListener;
+
+ EventList maActions;
+ osl::Mutex maMutex;
+ sal_Bool mbGotWelcome :1;
+ sal_Bool mbUseOne :1;
+ sal_Bool mbStatic :1;
+
+private:
+
+ void SendNotify();
+
+public:
+ SortedDynamicResultSet( const REFERENCE < XDYNAMICRESULTSET > &xOriginal,
+ const SEQUENCE < NUMBERED_SORTINGINFO > &aOptions,
+ const REFERENCE < XANYCOMPAREFACTORY > &xCompFac,
+ const REFERENCE < XMULTISERVICEFACTORY > &xSMgr );
+
+ ~SortedDynamicResultSet();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ //-----------------------------------------------------------------
+ XINTERFACE_DECL()
+
+ //-----------------------------------------------------------------
+ // XTypeProvider
+ //-----------------------------------------------------------------
+ XTYPEPROVIDER_DECL()
+
+ //-----------------------------------------------------------------
+ // XServiceInfo
+ //-----------------------------------------------------------------
+ XSERVICEINFO_NOFACTORY_DECL()
+
+ //-----------------------------------------------------------------
+ // XComponent
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ dispose() throw( RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ addEventListener( const REFERENCE< XEVENTLISTENER >& Listener )
+ throw( RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ removeEventListener( const REFERENCE< XEVENTLISTENER >& Listener )
+ throw( RUNTIME_EXCEPTION );
+
+ //-----------------------------------------------------------------
+ // XDynamicResultSet
+ //-----------------------------------------------------------------
+ virtual REFERENCE< XRESULTSET > SAL_CALL
+ getStaticResultSet( )
+ throw( LISTENERALREADYSETEXCEPTION, RUNTIMEEXCEPTION );
+
+ virtual void SAL_CALL
+ setListener( const REFERENCE< XDYNAMICRESULTSETLISTENER >& Listener )
+ throw( LISTENERALREADYSETEXCEPTION, RUNTIMEEXCEPTION );
+
+ virtual void SAL_CALL
+ connectToCache( const REFERENCE< XDYNAMICRESULTSET > & xCache )
+ throw( LISTENERALREADYSETEXCEPTION,
+ com::sun::star::ucb::AlreadyInitializedException,
+ com::sun::star::ucb::ServiceNotFoundException,
+ RUNTIMEEXCEPTION );
+
+ virtual sal_Int16 SAL_CALL
+ getCapabilities()
+ throw( RUNTIMEEXCEPTION );
+
+ //-----------------------------------------------------------------
+ // own methods:
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ impl_disposing( const EVENTOBJECT& Source )
+ throw( RUNTIMEEXCEPTION );
+
+ virtual void SAL_CALL
+ impl_notify( const ::com::sun::star::ucb::ListEvent& Changes )
+ throw( RUNTIMEEXCEPTION );
+};
+
+//-----------------------------------------------------------------------------
+
+class SortedDynamicResultSetListener:
+ public cppu::OWeakObject,
+ public com::sun::star::ucb::XDynamicResultSetListener
+{
+ SortedDynamicResultSet *mpOwner;
+ osl::Mutex maMutex;
+
+public:
+ SortedDynamicResultSetListener( SortedDynamicResultSet *mOwner );
+ ~SortedDynamicResultSetListener();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ //-----------------------------------------------------------------
+ XINTERFACE_DECL()
+
+ //-----------------------------------------------------------------
+ // XEventListener ( base of XDynamicResultSetListener )
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ disposing( const EVENTOBJECT& Source )
+ throw( RUNTIMEEXCEPTION );
+
+ //-----------------------------------------------------------------
+ // XDynamicResultSetListener
+ //-----------------------------------------------------------------
+ virtual void SAL_CALL
+ notify( const ::com::sun::star::ucb::ListEvent& Changes )
+ throw( RUNTIMEEXCEPTION );
+
+ //-----------------------------------------------------------------
+ // own methods:
+ //-----------------------------------------------------------------
+ void SAL_CALL impl_OwnerDies();
+};
+
+//-----------------------------------------------------------------------------
+
+class SortedDynamicResultSetFactory:
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::ucb::XSortedDynamicResultSetFactory
+{
+
+ REFERENCE< XMULTISERVICEFACTORY > mxSMgr;
+
+public:
+
+ SortedDynamicResultSetFactory(
+ const REFERENCE< XMULTISERVICEFACTORY > & rSMgr);
+
+ ~SortedDynamicResultSetFactory();
+
+ //-----------------------------------------------------------------
+ // XInterface
+ //-----------------------------------------------------------------
+ XINTERFACE_DECL()
+
+ //-----------------------------------------------------------------
+ // XTypeProvider
+ //-----------------------------------------------------------------
+ XTYPEPROVIDER_DECL()
+
+ //-----------------------------------------------------------------
+ // XServiceInfo
+ //-----------------------------------------------------------------
+ XSERVICEINFO_DECL()
+
+ //-----------------------------------------------------------------
+ // XSortedDynamicResultSetFactory
+
+ virtual REFERENCE< XDYNAMICRESULTSET > SAL_CALL
+ createSortedDynamicResultSet(
+ const REFERENCE< XDYNAMICRESULTSET > & Source,
+ const SEQUENCE< NUMBERED_SORTINGINFO > & Info,
+ const REFERENCE< XANYCOMPAREFACTORY > & CompareFactory )
+ throw( RUNTIMEEXCEPTION );
+};
+
+#endif
diff --git a/ucb/source/sorter/sortmain.cxx b/ucb/source/sorter/sortmain.cxx
new file mode 100644
index 000000000000..5ad9a529e1f2
--- /dev/null
+++ b/ucb/source/sorter/sortmain.cxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+#include <sortdynres.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+
+//=========================================================================
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//=========================================================================
+extern "C" void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * )
+{
+ void * pRet = 0;
+
+ Reference< XMultiServiceFactory > xSMgr(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ) );
+ Reference< XSingleServiceFactory > xFactory;
+
+ //////////////////////////////////////////////////////////////////////
+ // SortedDynamicResultSetFactory.
+ //////////////////////////////////////////////////////////////////////
+
+ if ( SortedDynamicResultSetFactory::getImplementationName_Static().
+ compareToAscii( pImplName ) == 0 )
+ {
+ xFactory = SortedDynamicResultSetFactory::createServiceFactory( xSMgr );
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+
+ return pRet;
+}
+
diff --git a/ucb/source/sorter/sortresult.cxx b/ucb/source/sorter/sortresult.cxx
new file mode 100644
index 000000000000..6e546950a23a
--- /dev/null
+++ b/ucb/source/sorter/sortresult.cxx
@@ -0,0 +1,2070 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_ucb.hxx"
+
+#include <vector>
+#include <sortresult.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/ucb/ListActionType.hpp>
+#include <com/sun/star/ucb/XAnyCompare.hpp>
+#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
+#include <osl/diagnose.h>
+
+//-----------------------------------------------------------------------------
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace com::sun::star::io;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::sdbc;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+using namespace cppu;
+using namespace rtl;
+
+//=========================================================================
+
+// The mutex to synchronize access to containers.
+static osl::Mutex& getContainerMutex()
+{
+ static osl::Mutex* pMutex = NULL;
+ if( !pMutex )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pMutex )
+ {
+ static osl::Mutex aMutex;
+ pMutex = &aMutex;
+ }
+ }
+
+ return *pMutex;
+}
+
+//==========================================================================
+
+struct SortInfo
+{
+ sal_Bool mbUseOwnCompare;
+ sal_Bool mbAscending;
+ sal_Bool mbCaseSensitive;
+ sal_Int32 mnColumn;
+ sal_Int32 mnType;
+ SortInfo* mpNext;
+ Reference < XAnyCompare > mxCompareFunction;
+};
+
+//-----------------------------------------------------------------------------
+
+struct SortListData
+{
+ sal_Bool mbModified;
+ long mnCurPos;
+ long mnOldPos;
+
+ SortListData( long nPos, sal_Bool bModified = sal_False );
+};
+
+//============================================================================
+//
+// class SRSPropertySetInfo.
+//
+//============================================================================
+
+class SRSPropertySetInfo :
+ public OWeakObject,
+ public XTypeProvider,
+ public XPropertySetInfo
+{
+ Property maProps[2];
+
+private:
+
+public:
+ SRSPropertySetInfo();
+ virtual ~SRSPropertySetInfo();
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XPropertySetInfo
+ virtual Sequence< Property > SAL_CALL getProperties()
+ throw( RuntimeException );
+ virtual Property SAL_CALL getPropertyByName( const OUString& aName )
+ throw( UnknownPropertyException, RuntimeException );
+ virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name )
+ throw( RuntimeException );
+};
+
+//=========================================================================
+//
+// PropertyChangeListenerContainer_Impl.
+//
+//=========================================================================
+
+struct equalStr_Impl
+{
+ bool operator()( const OUString& s1, const OUString& s2 ) const
+ {
+ return !!( s1 == s2 );
+ }
+};
+
+struct hashStr_Impl
+{
+ size_t operator()( const OUString& rName ) const
+ {
+ return rName.hashCode();
+ }
+};
+
+typedef OMultiTypeInterfaceContainerHelperVar
+<
+ OUString,
+ hashStr_Impl,
+ equalStr_Impl
+> PropertyChangeListenerContainer_Impl;
+
+//=========================================================================
+//
+// class PropertyChangeListeners_Impl
+//
+//=========================================================================
+
+class PropertyChangeListeners_Impl : public PropertyChangeListenerContainer_Impl
+{
+public:
+ PropertyChangeListeners_Impl()
+ : PropertyChangeListenerContainer_Impl( getContainerMutex() ) {}
+};
+
+//==========================================================================
+SortedResultSet::SortedResultSet( Reference< XResultSet > aResult )
+{
+ mpDisposeEventListeners = NULL;
+ mpPropChangeListeners = NULL;
+ mpVetoChangeListeners = NULL;
+ mpPropSetInfo = NULL;
+
+ mxOriginal = aResult;
+ mpSortInfo = NULL;
+ mnLastSort = 0;
+ mnCurEntry = 0;
+ mnCount = 0;
+ mbIsCopy = sal_False;
+}
+
+//--------------------------------------------------------------------------
+SortedResultSet::~SortedResultSet()
+{
+ mxOriginal.clear();
+ mxOther.clear();
+
+ if ( !mbIsCopy )
+ {
+ SortInfo *pInfo = mpSortInfo;
+ while ( pInfo )
+ {
+ mpSortInfo = pInfo->mpNext;
+ delete pInfo;
+ pInfo = mpSortInfo;
+ }
+ }
+
+ mpSortInfo = NULL;
+
+ if ( mpPropSetInfo )
+ mpPropSetInfo->release();
+
+ delete mpPropChangeListeners;
+ delete mpVetoChangeListeners;
+}
+
+//--------------------------------------------------------------------------
+// XInterface methods.
+//--------------------------------------------------------------------------
+
+XINTERFACE_IMPL_9( SortedResultSet,
+ XTypeProvider,
+ XServiceInfo,
+ XComponent,
+ XContentAccess,
+ XResultSet,
+ XRow,
+ XCloseable,
+ XResultSetMetaDataSupplier,
+ XPropertySet );
+
+//--------------------------------------------------------------------------
+// XTypeProvider methods.
+//--------------------------------------------------------------------------
+
+XTYPEPROVIDER_IMPL_9( SortedResultSet,
+ XTypeProvider,
+ XServiceInfo,
+ XComponent,
+ XContentAccess,
+ XResultSet,
+ XRow,
+ XCloseable,
+ XResultSetMetaDataSupplier,
+ XPropertySet );
+
+//--------------------------------------------------------------------------
+// XServiceInfo methods.
+//--------------------------------------------------------------------------
+
+XSERVICEINFO_NOFACTORY_IMPL_1( SortedResultSet,
+ OUString::createFromAscii(
+ "com.sun.star.comp.ucb.SortedResultSet" ),
+ OUString::createFromAscii(
+ RESULTSET_SERVICE_NAME ) );
+
+//--------------------------------------------------------------------------
+// XComponent methods.
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::dispose()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XComponent * >( this );
+ mpDisposeEventListeners->disposeAndClear( aEvt );
+ }
+
+ if ( mpPropChangeListeners )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ mpPropChangeListeners->disposeAndClear( aEvt );
+ }
+
+ if ( mpVetoChangeListeners )
+ {
+ EventObject aEvt;
+ aEvt.Source = static_cast< XPropertySet * >( this );
+ mpVetoChangeListeners->disposeAndClear( aEvt );
+ }
+
+ mxOriginal.clear();
+ mxOther.clear();
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::addEventListener(
+ const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpDisposeEventListeners )
+ mpDisposeEventListeners =
+ new OInterfaceContainerHelper( getContainerMutex() );
+
+ mpDisposeEventListeners->addInterface( Listener );
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::removeEventListener(
+ const Reference< XEventListener >& Listener )
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpDisposeEventListeners )
+ mpDisposeEventListeners->removeInterface( Listener );
+}
+
+//--------------------------------------------------------------------------
+// XContentAccess methods.
+//--------------------------------------------------------------------------
+
+OUString SAL_CALL
+SortedResultSet::queryContentIdentifierString()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifierString();
+}
+
+//--------------------------------------------------------------------------
+Reference< XContentIdentifier > SAL_CALL
+SortedResultSet::queryContentIdentifier()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifier();
+}
+
+//--------------------------------------------------------------------------
+Reference< XContent > SAL_CALL
+SortedResultSet::queryContent()
+ throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XContentAccess >::query(mxOriginal)->queryContent();
+}
+
+
+//--------------------------------------------------------------------------
+// XResultSet methods.
+//--------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::next()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ mnCurEntry++;
+
+ if ( mnCurEntry > 0 )
+ {
+ if ( mnCurEntry <= mnCount )
+ {
+ sal_Int32 nIndex = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nIndex );
+ }
+ else
+ {
+ mnCurEntry = mnCount + 1;
+ }
+ }
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::isBeforeFirst()
+ throw ( SQLException, RuntimeException )
+{
+ if ( mnCurEntry )
+ return sal_False;
+ else
+ return sal_True;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::isAfterLast()
+ throw ( SQLException, RuntimeException )
+{
+ if ( mnCurEntry > mnCount )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::isFirst()
+ throw ( SQLException, RuntimeException )
+{
+ if ( mnCurEntry == 1 )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::isLast()
+ throw ( SQLException, RuntimeException )
+{
+ if ( mnCurEntry == mnCount )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::beforeFirst()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ mnCurEntry = 0;
+ mxOriginal->beforeFirst();
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::afterLast()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ mnCurEntry = mnCount+1;
+ mxOriginal->afterLast();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::first()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mnCount )
+ {
+ mnCurEntry = 1;
+ sal_Int32 nIndex = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nIndex );
+ }
+ else
+ {
+ mnCurEntry = 0;
+ return sal_False;
+ }
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::last()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mnCount )
+ {
+ mnCurEntry = mnCount;
+ sal_Int32 nIndex = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nIndex );
+ }
+ else
+ {
+ mnCurEntry = 0;
+ return sal_False;
+ }
+}
+
+//-------------------------------------------------------------------------
+sal_Int32 SAL_CALL SortedResultSet::getRow()
+ throw ( SQLException, RuntimeException )
+{
+ return mnCurEntry;
+}
+
+//-------------------------------------------------------------------------
+/**
+ moves the cursor to the given row number in the result set.
+ <p>If the row number is positive, the cursor moves to the given row
+ number with respect to the beginning of the result set. The first
+ row is row 1, the second is row 2, and so on.
+ <p>If the given row number is negative, the cursor moves to an
+ absolute row position with respect to the end of the result set.
+ For example, calling <code>moveToPosition(-1)</code> positions the
+ cursor on the last row, <code>moveToPosition(-2)</code> indicates the
+ next-to-last row, and so on.
+ <p>An attempt to position the cursor beyond the first/last row in the
+ result set leaves the cursor before/after the first/last row,
+ respectively.
+ <p>Note: Calling <code>moveToPosition(1)</code> is the same
+ as calling <code>moveToFirst()</code>. Calling
+ <code>moveToPosition(-1)</code> is the same as calling
+ <code>moveToLast()</code>.
+ @param row
+ is the number of rows to move. Could be negative.
+ @returns
+ <sal_True/> if the cursor is on a row; <sal_False/> otherwise
+ @throws SQLException
+ if a database access error occurs or if row is 0, or the result set
+ type is FORWARD_ONLY.
+ */
+sal_Bool SAL_CALL SortedResultSet::absolute( sal_Int32 row )
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ sal_Int32 nIndex;
+
+ if ( row > 0 )
+ {
+ if ( row <= mnCount )
+ {
+ mnCurEntry = row;
+ nIndex = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nIndex );
+ }
+ else
+ {
+ mnCurEntry = mnCount + 1;
+ return sal_False;
+ }
+ }
+ else if ( row == 0 )
+ {
+ throw SQLException();
+ }
+ else
+ {
+ if ( mnCount + row + 1 > 0 )
+ {
+ mnCurEntry = mnCount + row + 1;
+ nIndex = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nIndex );
+ }
+ else
+ {
+ mnCurEntry = 0;
+ return sal_False;
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+/**
+ moves the cursor a relative number of rows, either positive or negative.
+ <p>
+ Attempting to move beyond the first/last row in the result set positions
+ the cursor before/after the first/last row. Calling
+ <code>moveRelative(0)</code> is valid, but does not change the cursor
+ position.
+ <p>Note: Calling <code>moveRelative(1)</code> is different from calling
+ <code>moveNext()</code> because is makes sense to call
+ <code>moveNext()</code> when there is no current row, for example,
+ when the cursor is positioned before the first row or after the last
+ row of the result set.
+ @param rows
+ is the number of rows to move. Could be negative.
+ @returns
+ <sal_True/> if the cursor is on a valid row; <sal_False/> if it is off
+ the result set.
+ @throws SQLException
+ if a database access error occurs or if there is no
+ current row, or the result set type is FORWARD_ONLY.
+ */
+sal_Bool SAL_CALL SortedResultSet::relative( sal_Int32 rows )
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
+ {
+ throw SQLException();
+ }
+
+ if ( rows == 0 )
+ return sal_True;
+
+ sal_Int32 nTmp = mnCurEntry + rows;
+
+ if ( nTmp <= 0 )
+ {
+ mnCurEntry = 0;
+ return sal_False;
+ }
+ else if ( nTmp > mnCount )
+ {
+ mnCurEntry = mnCount + 1;
+ return sal_False;
+ }
+ else
+ {
+ mnCurEntry = nTmp;
+ nTmp = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nTmp );
+ }
+}
+
+//-------------------------------------------------------------------------
+/**
+ moves the cursor to the previous row in the result set.
+ <p>Note: <code>previous()</code> is not the same as
+ <code>relative(-1)</code> because it makes sense to call
+ <code>previous()</code> when there is no current row.
+ @returns <sal_True/> if the cursor is on a valid row; <sal_False/> if it is off
+ the result set.
+ @throws SQLException
+ if a database access error occurs or the result set type
+ is FORWARD_ONLY.
+ */
+sal_Bool SAL_CALL SortedResultSet::previous()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ mnCurEntry -= 1;
+
+ if ( mnCurEntry > 0 )
+ {
+ if ( mnCurEntry <= mnCount )
+ {
+ sal_Int32 nIndex = maS2O[ mnCurEntry ];
+ return mxOriginal->absolute( nIndex );
+ }
+ }
+ else
+ mnCurEntry = 0;
+
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::refreshRow()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
+ {
+ throw SQLException();
+ }
+
+ mxOriginal->refreshRow();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::rowUpdated()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
+ {
+ throw SQLException();
+ }
+
+ return mxOriginal->rowUpdated();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::rowInserted()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
+ {
+ throw SQLException();
+ }
+
+ return mxOriginal->rowInserted();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::rowDeleted()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
+ {
+ throw SQLException();
+ }
+
+ return mxOriginal->rowDeleted();
+}
+
+//-------------------------------------------------------------------------
+Reference< XInterface > SAL_CALL SortedResultSet::getStatement()
+ throw ( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
+ {
+ throw SQLException();
+ }
+
+ return mxOriginal->getStatement();
+}
+
+//--------------------------------------------------------------------------
+// XRow methods.
+//--------------------------------------------------------------------------
+
+sal_Bool SAL_CALL SortedResultSet::wasNull()
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->wasNull();
+}
+
+//-------------------------------------------------------------------------
+OUString SAL_CALL SortedResultSet::getString( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getString( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL SortedResultSet::getBoolean( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getBoolean( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+sal_Int8 SAL_CALL SortedResultSet::getByte( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getByte( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+sal_Int16 SAL_CALL SortedResultSet::getShort( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getShort( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+sal_Int32 SAL_CALL SortedResultSet::getInt( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getInt( columnIndex );
+}
+//-------------------------------------------------------------------------
+sal_Int64 SAL_CALL SortedResultSet::getLong( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getLong( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+float SAL_CALL SortedResultSet::getFloat( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getFloat( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+double SAL_CALL SortedResultSet::getDouble( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getDouble( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Sequence< sal_Int8 > SAL_CALL SortedResultSet::getBytes( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getBytes( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Date SAL_CALL SortedResultSet::getDate( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getDate( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Time SAL_CALL SortedResultSet::getTime( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getTime( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+DateTime SAL_CALL SortedResultSet::getTimestamp( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getTimestamp( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Reference< XInputStream > SAL_CALL
+SortedResultSet::getBinaryStream( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getBinaryStream( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Reference< XInputStream > SAL_CALL
+SortedResultSet::getCharacterStream( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getCharacterStream( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Any SAL_CALL SortedResultSet::getObject( sal_Int32 columnIndex,
+ const Reference< XNameAccess >& typeMap )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getObject( columnIndex,
+ typeMap);
+}
+
+//-------------------------------------------------------------------------
+Reference< XRef > SAL_CALL SortedResultSet::getRef( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getRef( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Reference< XBlob > SAL_CALL SortedResultSet::getBlob( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getBlob( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Reference< XClob > SAL_CALL SortedResultSet::getClob( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getClob( columnIndex );
+}
+
+//-------------------------------------------------------------------------
+Reference< XArray > SAL_CALL SortedResultSet::getArray( sal_Int32 columnIndex )
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XRow >::query(mxOriginal)->getArray( columnIndex );
+}
+
+
+//--------------------------------------------------------------------------
+// XCloseable methods.
+//--------------------------------------------------------------------------
+
+void SAL_CALL SortedResultSet::close()
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ Reference< XCloseable >::query(mxOriginal)->close();
+}
+
+//--------------------------------------------------------------------------
+// XResultSetMetaDataSupplier methods.
+//--------------------------------------------------------------------------
+
+Reference< XResultSetMetaData > SAL_CALL SortedResultSet::getMetaData()
+ throw( SQLException, RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+ return Reference< XResultSetMetaDataSupplier >::query(mxOriginal)->getMetaData();
+}
+
+
+//--------------------------------------------------------------------------
+// XPropertySet methods.
+//--------------------------------------------------------------------------
+
+Reference< XPropertySetInfo > SAL_CALL
+SortedResultSet::getPropertySetInfo() throw( RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpPropSetInfo )
+ {
+ mpPropSetInfo = new SRSPropertySetInfo();
+ mpPropSetInfo->acquire();
+ }
+
+ return Reference< XPropertySetInfo >( mpPropSetInfo );
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::setPropertyValue(
+ const OUString& PropertyName,
+ const Any& )
+ throw( UnknownPropertyException,
+ PropertyVetoException,
+ IllegalArgumentException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( ( PropertyName.compareToAscii( "RowCount" ) == 0 ) ||
+ ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 ) )
+ throw IllegalArgumentException();
+ else
+ throw UnknownPropertyException();
+}
+
+//--------------------------------------------------------------------------
+Any SAL_CALL SortedResultSet::getPropertyValue( const OUString& PropertyName )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ Any aRet;
+
+ if ( PropertyName.compareToAscii( "RowCount" ) == 0 )
+ {
+ aRet <<= maS2O.Count();
+ }
+ else if ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 )
+ {
+ sal_uInt32 nOrgCount = 0;
+ sal_Bool bOrgFinal = false;
+ Any aOrgRet;
+
+ aRet <<= (sal_Bool) sal_False;
+
+ aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
+ getPropertyValue( PropertyName );
+ aOrgRet >>= bOrgFinal;
+
+ if ( bOrgFinal )
+ {
+ aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
+ getPropertyValue( OUString::createFromAscii( "RowCount" ) );
+ aOrgRet >>= nOrgCount;
+ if ( nOrgCount == maS2O.Count() )
+ aRet <<= (sal_Bool) sal_True;
+ }
+ }
+ else
+ throw UnknownPropertyException();
+
+ return aRet;
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::addPropertyChangeListener(
+ const OUString& PropertyName,
+ const Reference< XPropertyChangeListener >& Listener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpPropChangeListeners )
+ mpPropChangeListeners =
+ new PropertyChangeListeners_Impl();
+
+ mpPropChangeListeners->addInterface( PropertyName, Listener );
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::removePropertyChangeListener(
+ const OUString& PropertyName,
+ const Reference< XPropertyChangeListener >& Listener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpPropChangeListeners )
+ mpPropChangeListeners->removeInterface( PropertyName, Listener );
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::addVetoableChangeListener(
+ const OUString& PropertyName,
+ const Reference< XVetoableChangeListener >& Listener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpVetoChangeListeners )
+ mpVetoChangeListeners =
+ new PropertyChangeListeners_Impl();
+
+ mpVetoChangeListeners->addInterface( PropertyName, Listener );
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL SortedResultSet::removeVetoableChangeListener(
+ const OUString& PropertyName,
+ const Reference< XVetoableChangeListener >& Listener )
+ throw( UnknownPropertyException,
+ WrappedTargetException,
+ RuntimeException )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( mpVetoChangeListeners )
+ mpVetoChangeListeners->removeInterface( PropertyName, Listener );
+}
+
+//--------------------------------------------------------------------------
+// private methods
+//--------------------------------------------------------------------------
+long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
+ Reference < XResultSet > xResultTwo,
+ long nIndexOne, long nIndexTwo,
+ SortInfo* pSortInfo )
+
+ throw( SQLException, RuntimeException )
+{
+ Reference < XRow > xRowOne = Reference< XRow >::query( xResultOne );
+ Reference < XRow > xRowTwo = Reference< XRow >::query( xResultTwo );
+
+ long nCompare = 0;
+ long nColumn = pSortInfo->mnColumn;
+
+ switch ( pSortInfo->mnType )
+ {
+ case DataType::BIT :
+ case DataType::TINYINT :
+ case DataType::SMALLINT :
+ case DataType::INTEGER :
+ {
+ sal_Int32 aOne = 0;
+ sal_Int32 aTwo = 0;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getInt( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getInt( nColumn );
+
+ if ( aOne < aTwo )
+ nCompare = -1;
+ else if ( aOne == aTwo )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ case DataType::BIGINT :
+ {
+ sal_Int64 aOne = 0;
+ sal_Int64 aTwo = 0;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getLong( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getLong( nColumn );
+
+ if ( aOne < aTwo )
+ nCompare = -1;
+ else if ( aOne == aTwo )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ case DataType::CHAR :
+ case DataType::VARCHAR :
+ case DataType::LONGVARCHAR :
+ {
+ OUString aOne, aTwo;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getString( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getString( nColumn );
+
+ if ( ! pSortInfo->mbCaseSensitive )
+ {
+ aOne = aOne.toAsciiLowerCase();
+ aTwo = aTwo.toAsciiLowerCase();
+ }
+
+ nCompare = aOne.compareTo( aTwo );
+ break;
+ }
+ case DataType::DATE :
+ {
+ Date aOne, aTwo;
+ sal_Int32 nTmp;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getDate( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getDate( nColumn );
+
+ nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
+ if ( !nTmp )
+ nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
+ }
+
+ if ( nTmp < 0 )
+ nCompare = -1;
+ else if ( nTmp == 0 )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ case DataType::TIME :
+ {
+ Time aOne, aTwo;
+ sal_Int32 nTmp;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getTime( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getTime( nColumn );
+
+ nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
+ if ( !nTmp )
+ nTmp = (sal_Int32) aTwo.HundredthSeconds
+ - (sal_Int32) aOne.HundredthSeconds;
+ }}
+
+ if ( nTmp < 0 )
+ nCompare = -1;
+ else if ( nTmp == 0 )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ case DataType::TIMESTAMP :
+ {
+ DateTime aOne, aTwo;
+ sal_Int32 nTmp;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getTimestamp( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getTimestamp( nColumn );
+
+ nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
+ if ( !nTmp ) {
+ nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
+ if ( !nTmp )
+ nTmp = (sal_Int32) aTwo.HundredthSeconds
+ - (sal_Int32) aOne.HundredthSeconds;
+ }}}}}
+
+ if ( nTmp < 0 )
+ nCompare = -1;
+ else if ( nTmp == 0 )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ case DataType::REAL :
+ {
+ float aOne = 0;
+ float aTwo = 0;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getFloat( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getFloat( nColumn );
+
+ if ( aOne < aTwo )
+ nCompare = -1;
+ else if ( aOne == aTwo )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ case DataType::FLOAT :
+ case DataType::DOUBLE :
+ {
+ double aOne = 0;
+ double aTwo = 0;
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getDouble( nColumn );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getDouble( nColumn );
+
+ if ( aOne < aTwo )
+ nCompare = -1;
+ else if ( aOne == aTwo )
+ nCompare = 0;
+ else
+ nCompare = 1;
+
+ break;
+ }
+ default:
+ {
+ OSL_ENSURE( sal_False, "DataType not supported for compare!" );
+ }
+ }
+
+ return nCompare;
+}
+
+//--------------------------------------------------------------------------
+long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
+ Reference < XResultSet > xResultTwo,
+ long nIndexOne, long nIndexTwo )
+ throw( SQLException, RuntimeException )
+{
+ long nCompare = 0;
+ SortInfo* pInfo = mpSortInfo;
+
+ while ( !nCompare && pInfo )
+ {
+ if ( pInfo->mbUseOwnCompare )
+ {
+ nCompare = CompareImpl( xResultOne, xResultTwo,
+ nIndexOne, nIndexTwo, pInfo );
+ }
+ else
+ {
+ Any aOne, aTwo;
+
+ Reference < XRow > xRowOne =
+ Reference< XRow >::query( xResultOne );
+ Reference < XRow > xRowTwo =
+ Reference< XRow >::query( xResultTwo );
+
+ if ( xResultOne->absolute( nIndexOne ) )
+ aOne = xRowOne->getObject( pInfo->mnColumn, NULL );
+ if ( xResultTwo->absolute( nIndexTwo ) )
+ aTwo = xRowTwo->getObject( pInfo->mnColumn, NULL );
+
+ nCompare = pInfo->mxCompareFunction->compare( aOne, aTwo );
+ }
+
+ if ( ! pInfo->mbAscending )
+ nCompare = - nCompare;
+
+ pInfo = pInfo->mpNext;
+ }
+
+ return nCompare;
+}
+
+//--------------------------------------------------------------------------
+long SortedResultSet::Compare( SortListData *pOne,
+ SortListData *pTwo )
+ throw( SQLException, RuntimeException )
+{
+ long nIndexOne;
+ long nIndexTwo;
+
+ Reference < XResultSet > xResultOne;
+ Reference < XResultSet > xResultTwo;
+
+ if ( pOne->mbModified )
+ {
+ xResultOne = mxOther;
+ nIndexOne = pOne->mnOldPos;
+ }
+ else
+ {
+ xResultOne = mxOriginal;
+ nIndexOne = pOne->mnCurPos;
+ }
+
+ if ( pTwo->mbModified )
+ {
+ xResultTwo = mxOther;
+ nIndexTwo = pTwo->mnOldPos;
+ }
+ else
+ {
+ xResultTwo = mxOriginal;
+ nIndexTwo = pTwo->mnCurPos;
+ }
+
+ long nCompare;
+ nCompare = CompareImpl( xResultOne, xResultTwo,
+ nIndexOne, nIndexTwo );
+ return nCompare;
+}
+
+//--------------------------------------------------------------------------
+long SortedResultSet::FindPos( SortListData *pEntry,
+ long _nStart, long _nEnd )
+ throw( SQLException, RuntimeException )
+{
+ if ( _nStart > _nEnd )
+ return _nStart + 1;
+
+ long nStart = _nStart;
+ long nEnd = _nEnd;
+ long nMid = 0, nCompare = 0;
+
+ SortListData *pMid;
+
+ while ( nStart <= nEnd )
+ {
+ nMid = ( nEnd - nStart ) / 2 + nStart;
+ pMid = maS2O.GetData( nMid );
+ nCompare = Compare( pEntry, pMid );
+
+ if ( !nCompare )
+ nCompare = ((long) pEntry ) - ( (long) pMid );
+
+ if ( nCompare < 0 ) // pEntry < pMid
+ nEnd = nMid - 1;
+ else
+ nStart = nMid + 1;
+ }
+
+ if ( nCompare < 0 ) // pEntry < pMid
+ return nMid;
+ else
+ return nMid+1;
+}
+
+//--------------------------------------------------------------------------
+void SortedResultSet::PropertyChanged( const PropertyChangeEvent& rEvt )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpPropChangeListeners )
+ return;
+
+ // Notify listeners interested especially in the changed property.
+ OInterfaceContainerHelper* pPropsContainer =
+ mpPropChangeListeners->getContainer( rEvt.PropertyName );
+ if ( pPropsContainer )
+ {
+ OInterfaceIteratorHelper aIter( *pPropsContainer );
+ while ( aIter.hasMoreElements() )
+ {
+ Reference< XPropertyChangeListener > xListener(
+ aIter.next(), UNO_QUERY );
+ if ( xListener.is() )
+ xListener->propertyChange( rEvt );
+ }
+ }
+
+ // Notify listeners interested in all properties.
+ pPropsContainer = mpPropChangeListeners->getContainer( OUString() );
+ if ( pPropsContainer )
+ {
+ OInterfaceIteratorHelper aIter( *pPropsContainer );
+ while ( aIter.hasMoreElements() )
+ {
+ Reference< XPropertyChangeListener > xListener(
+ aIter.next(), UNO_QUERY );
+ if ( xListener.is() )
+ xListener->propertyChange( rEvt );
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------
+// public methods
+//--------------------------------------------------------------------------
+
+void SortedResultSet::CopyData( SortedResultSet *pSource )
+{
+ const SortedEntryList *pSrcS2O = pSource->GetS2OList();
+ const SimpleList *pSrcO2S = pSource->GetO2SList();
+
+ long i, nCount;
+
+ maS2O.Clear();
+ maO2S.Clear();
+ maModList.Clear();
+
+ maS2O.Insert( NULL, 0 );
+ maO2S.Insert( 0, (sal_uInt32) 0 ); // value, pos
+
+ nCount = pSrcS2O->Count();
+
+ for ( i=1; i<nCount; i++ )
+ {
+ maS2O.Insert( new SortListData( (*pSrcS2O)[ i ] ), i );
+ maO2S.Insert( pSrcO2S->GetObject( i ), (sal_uInt32) i );
+ }
+
+ mnLastSort = maS2O.Count();
+ mxOther = pSource->GetResultSet();
+
+ if ( !mpSortInfo )
+ {
+ mpSortInfo = pSource->GetSortInfo();
+ mbIsCopy = sal_True;
+ }
+}
+
+//--------------------------------------------------------------------------
+void SortedResultSet::Initialize(
+ const Sequence < NumberedSortingInfo > &xSortInfo,
+ const Reference< XAnyCompareFactory > &xCompFactory )
+{
+ BuildSortInfo( mxOriginal, xSortInfo, xCompFactory );
+ // Insert dummy at pos 0
+ SortListData *pData = new SortListData( 0 );
+ maS2O.Insert( pData, 0 );
+
+ long nIndex = 1;
+
+ // now fetch all the elements from the original result set,
+ // get there new position in the sorted result set and insert
+ // an entry in the sorted to original mapping list
+ try {
+ while ( mxOriginal->absolute( nIndex ) )
+ {
+ pData = new SortListData( nIndex );
+ long nPos = FindPos( pData, 1, nIndex-1 );
+
+ maS2O.Insert( pData, nPos );
+
+ nIndex++;
+ }
+ }
+ catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::Initialize() : Got unexpected SQLException" ); }
+
+ // when we have fetched all the elements, we can create the
+ // original to sorted mapping list from the s2o list
+ maO2S.Clear();
+ maO2S.Insert( NULL, (sal_uInt32) 0 );
+
+ // insert some dummy entries first and replace then
+ // the entries with the right ones
+ sal_uInt32 i;
+
+ for ( i=1; i<maS2O.Count(); i++ )
+ maO2S.Insert( (void*) 0, i ); // Insert( data, pos )
+ for ( i=1; i<maS2O.Count(); i++ )
+ maO2S.Replace( (void*) i, maS2O[ i ] ); // Insert( data, pos )
+
+ mnCount = maS2O.Count() - 1;
+}
+
+//--------------------------------------------------------------------------
+void SortedResultSet::CheckProperties( long nOldCount, sal_Bool bWasFinal )
+{
+ osl::Guard< osl::Mutex > aGuard( maMutex );
+
+ if ( !mpPropChangeListeners )
+ return;
+
+ try {
+ // check for propertyChangeEvents
+ if ( nOldCount != GetCount() )
+ {
+ sal_Bool bIsFinal = sal_False;
+ PropertyChangeEvent aEvt;
+
+ aEvt.PropertyName = OUString::createFromAscii( "RowCount" );
+ aEvt.Further = sal_False;
+ aEvt.PropertyHandle = -1;
+ aEvt.OldValue <<= nOldCount;
+ aEvt.NewValue <<= GetCount();
+
+ PropertyChanged( aEvt );
+
+ OUString aName = OUString::createFromAscii( "IsRowCountFinal" );
+ Any aRet = getPropertyValue( aName );
+ if ( (aRet >>= bIsFinal) && bIsFinal != bWasFinal )
+ {
+ aEvt.PropertyName = aName;
+ aEvt.Further = sal_False;
+ aEvt.PropertyHandle = -1;
+ aEvt.OldValue <<= (sal_Bool) bWasFinal;
+ aEvt.NewValue <<= (sal_Bool) bIsFinal;
+ PropertyChanged( aEvt );
+ }
+ }
+ }
+ catch ( UnknownPropertyException ) {}
+ catch ( WrappedTargetException ) {}
+}
+
+//-------------------------------------------------------------------------
+void SortedResultSet::InsertNew( long nPos, long nCount )
+{
+ // in der maS2O Liste alle Einträge, die >= nPos sind, um nCount
+ // erhöhen
+ SortListData *pData;
+ long i, nEnd;
+
+ nEnd = maS2O.Count();
+ for ( i=1; i<=nEnd; i++ )
+ {
+ pData = maS2O.GetData( i );
+ if ( pData->mnCurPos >= nPos )
+ {
+ pData->mnCurPos += nCount;
+ }
+ }
+
+ // und die neuen einträge hinten an die maS2O Liste anhängen bzw
+ // an der Position nPos in der maO2S Liste einfügen
+ for ( i=0; i<nCount; i++ )
+ {
+ nEnd += 1;
+ pData = new SortListData( nEnd );
+
+ maS2O.Insert( pData, nEnd ); // Insert( Wert, Position )
+ maO2S.Insert( (void*)nEnd, (sal_uInt32)(nPos+i) ); // Insert( Wert, Position )
+ }
+
+ mnCount += nCount;
+}
+
+//-------------------------------------------------------------------------
+void SortedResultSet::Remove( long nPos, long nCount, EventList *pEvents )
+{
+ sal_uInt32 i, j;
+ long nOldLastSort;
+
+ // correct mnLastSort first
+ nOldLastSort = mnLastSort;
+ if ( nPos <= mnLastSort )
+ {
+ if ( nPos + nCount - 1 <= mnLastSort )
+ mnLastSort -= nCount;
+ else
+ mnLastSort = nPos - 1;
+ }
+
+ // remove the entries from the lists and correct the positions
+ // in the original2sorted list
+ for ( i=0; i < (sal_uInt32) nCount; i++ )
+ {
+ long nSortPos = (long) maO2S.GetObject( nPos );
+ maO2S.Remove( (sal_uInt32) nPos );
+
+ for ( j=1; j<=maO2S.Count(); j++ )
+ {
+ long nVal = (long) maO2S.GetObject( j );
+ if ( nVal > nSortPos )
+ {
+ --nVal;
+ maO2S.Replace( (void*) nVal, j );
+ }
+ }
+
+ SortListData *pData = maS2O.Remove( nSortPos );
+ if ( pData->mbModified )
+ maModList.Remove( (void*) pData );
+ delete pData;
+
+ // generate remove Event, but not for new entries
+ if ( nSortPos <= nOldLastSort )
+ pEvents->AddEvent( ListActionType::REMOVED, nSortPos, 1 );
+ }
+
+ // correct the positions in the sorted list
+ for ( i=1; i<= maS2O.Count(); i++ )
+ {
+ SortListData *pData = maS2O.GetData( i );
+ if ( pData->mnCurPos > nPos )
+ pData->mnCurPos -= nCount;
+ }
+
+ mnCount -= nCount;
+}
+
+//-------------------------------------------------------------------------
+void SortedResultSet::Move( long nPos, long nCount, long nOffset )
+{
+ if ( !nOffset )
+ return;
+
+ long i, nSortPos, nTo;
+ SortListData *pData;
+
+ for ( i=0; i<nCount; i++ )
+ {
+ nSortPos = (long) maO2S.GetObject( nPos+i );
+ pData = maS2O.GetData( nSortPos );
+ pData->mnCurPos += nOffset;
+ }
+
+ if ( nOffset < 0 )
+ {
+ for ( i=nPos+nOffset; i<nPos; i++ )
+ {
+ nSortPos = (long) maO2S.GetObject( i );
+ pData = maS2O.GetData( nSortPos );
+ pData->mnCurPos += nCount;
+ }
+ }
+ else
+ {
+ long nStart = nPos + nCount;
+ long nEnd = nStart + nOffset;
+ for ( i=nStart; i<nEnd; i++ )
+ {
+ nSortPos = (long) maO2S.GetObject( i );
+ pData = maS2O.GetData( nSortPos );
+ pData->mnCurPos -= nCount;
+ }
+ }
+
+ // remember the to be moved entries
+ long *pTmpArr = new long[ nCount ];
+ for ( i=0; i<nCount; i++ )
+ pTmpArr[i] = (long)maO2S.GetObject( (sal_uInt32)( nPos+i ) );
+
+ // now move the entries, which are in the way
+ if ( nOffset < 0 )
+ {
+ // be carefully here, because nOffset is negative here, so an
+ // addition is a subtraction
+ long nFrom = nPos - 1;
+ nTo = nPos + nCount - 1;
+
+ // same for i here
+ for ( i=0; i>nOffset; i-- )
+ {
+ long nVal = (long) maO2S.GetObject( (sal_uInt32)( nFrom+i ) );
+ maO2S.Replace( (void*) nVal, (sal_uInt32)( nTo+i ) );
+ }
+
+ }
+ else
+ {
+ long nStart = nPos + nCount;
+ for ( i=0; i<nOffset; i++ )
+ {
+ long nVal = (long) maO2S.GetObject( (sal_uInt32)( nStart+i ) );
+ maO2S.Replace( (void*) nVal, (sal_uInt32)( nPos+i ) );
+ }
+ }
+
+ // finally put the remembered entries at there new location
+ nTo = nPos + nOffset;
+ for ( i=0; i<nCount; i++ )
+ {
+ maO2S.Replace( (void*)pTmpArr[ i ], (sal_uInt32)( nTo+i ) );
+ }
+
+ delete [] pTmpArr;
+}
+
+//--------------------------------------------------------------------------
+void SortedResultSet::BuildSortInfo(
+ Reference< XResultSet > aResult,
+ const Sequence < NumberedSortingInfo > &xSortInfo,
+ const Reference< XAnyCompareFactory > &xCompFactory )
+{
+ Reference < XResultSetMetaDataSupplier > xMeta ( aResult, UNO_QUERY );
+
+ if ( ! xMeta.is() )
+ {
+ OSL_ENSURE( sal_False, "No MetaData, No Sorting!" );
+ return;
+ }
+
+ Reference < XResultSetMetaData > xData = xMeta->getMetaData();
+ const NumberedSortingInfo *pSortInfo = xSortInfo.getConstArray();
+
+ sal_Int32 nColumn;
+ OUString aPropName;
+ SortInfo *pInfo;
+
+ for ( long i=xSortInfo.getLength(); i > 0; )
+ {
+ --i;
+ nColumn = pSortInfo[ i ].ColumnIndex;
+ aPropName = xData->getColumnName( nColumn );
+ pInfo = new SortInfo;
+
+ if ( xCompFactory.is() )
+ pInfo->mxCompareFunction = xCompFactory->createAnyCompareByName(
+ aPropName );
+
+ if ( pInfo->mxCompareFunction.is() )
+ {
+ pInfo->mbUseOwnCompare = sal_False;
+ pInfo->mnType = 0;
+ }
+ else
+ {
+ pInfo->mbUseOwnCompare = sal_True;
+ pInfo->mnType = xData->getColumnType( nColumn );
+ }
+
+ pInfo->mnColumn = nColumn;
+ pInfo->mbAscending = pSortInfo[ i ].Ascending;
+ pInfo->mbCaseSensitive = xData->isCaseSensitive( nColumn );
+ pInfo->mpNext = mpSortInfo;
+ mpSortInfo = pInfo;
+ }
+}
+
+//-------------------------------------------------------------------------
+void SortedResultSet::SetChanged( long nPos, long nCount )
+{
+ for ( long i=0; i<nCount; i++ )
+ {
+ long nSortPos = (long) maO2S.GetObject( nPos );
+ if ( nSortPos < mnLastSort )
+ {
+ SortListData *pData = maS2O.GetData( nSortPos );
+ if ( ! pData->mbModified )
+ {
+ pData->mbModified = sal_True;
+ maModList.Append( pData );
+ }
+ }
+ nPos += 1;
+ }
+}
+
+//-------------------------------------------------------------------------
+void SortedResultSet::ResortModified( EventList* pList )
+{
+ sal_uInt32 i, j;
+ long nCompare, nCurPos, nNewPos;
+ long nStart, nEnd, nOffset, nVal;
+ SortListData *pData;
+ ListAction *pAction;
+
+ try {
+ for ( i=0; i<maModList.Count(); i++ )
+ {
+ pData = (SortListData*) maModList.GetObject( i );
+ nCompare = CompareImpl( mxOther, mxOriginal,
+ pData->mnOldPos, pData->mnCurPos );
+ pData->mbModified = sal_False;
+ if ( nCompare != 0 )
+ {
+ nCurPos = (long) maO2S.GetObject( (sal_uInt32) pData->mnCurPos );
+ if ( nCompare < 0 )
+ {
+ nNewPos = FindPos( pData, 1, nCurPos-1 );
+ nStart = nNewPos;
+ nEnd = nCurPos;
+ nOffset = 1;
+ }
+ else
+ {
+ nNewPos = FindPos( pData, nCurPos+1, mnLastSort );
+ nStart = nCurPos;
+ nEnd = mnLastSort;
+ nOffset = -1;
+ }
+
+ if ( nNewPos != nCurPos )
+ {
+ // correct the lists!
+ maS2O.Remove( (sal_uInt32) nCurPos );
+ maS2O.Insert( pData, nNewPos );
+ for ( j=1; j<maO2S.Count(); j++ )
+ {
+ nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) );
+ if ( ( nStart <= nVal ) && ( nVal <= nEnd ) )
+ {
+ nVal += nOffset;
+ maO2S.Replace( (void*) (nVal), (sal_uInt32)( j ) );
+ }
+ }
+
+ maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
+
+ pAction = new ListAction;
+ pAction->Position = nCurPos;
+ pAction->Count = 1;
+ pAction->ListActionType = ListActionType::MOVED;
+ pAction->ActionInfo <<= nNewPos-nCurPos;
+ pList->Insert( pAction );
+ }
+ pList->AddEvent( ListActionType::PROPERTIES_CHANGED,
+ nNewPos, 1 );
+ }
+ }
+ }
+ catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::ResortModified() : Got unexpected SQLException" ); }
+
+ maModList.Clear();
+}
+
+//-------------------------------------------------------------------------
+void SortedResultSet::ResortNew( EventList* pList )
+{
+ long i, j, nNewPos, nVal;
+ SortListData *pData;
+
+ try {
+ for ( i = mnLastSort; i<(long)maS2O.Count(); i++ )
+ {
+ pData = (SortListData*) maModList.GetObject( i );
+ nNewPos = FindPos( pData, 1, mnLastSort );
+ if ( nNewPos != i )
+ {
+ maS2O.Remove( (sal_uInt32) i );
+ maS2O.Insert( pData, nNewPos );
+ // maO2S liste korigieren
+ for ( j=1; j<(long)maO2S.Count(); j++ )
+ {
+ nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) );
+ if ( nVal >= nNewPos )
+ maO2S.Replace( (void*) (nVal+1), (sal_uInt32)( j ) );
+ }
+ maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
+ }
+ mnLastSort++;
+ pList->AddEvent( ListActionType::INSERTED, nNewPos, 1 );
+ }
+ }
+ catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::ResortNew() : Got unexpected SQLException" ); }
+}
+
+//-------------------------------------------------------------------------
+//
+// SortListData
+//
+//-------------------------------------------------------------------------
+SortListData::SortListData( long nPos, sal_Bool bModified )
+{
+ mbModified = bModified;
+ mnCurPos = nPos;
+ mnOldPos = nPos;
+};
+
+
+//=========================================================================
+void SortedEntryList::Clear()
+{
+ for ( std::deque< LISTACTION* >::size_type i = 0;
+ i < maData.size(); ++i )
+ {
+ delete maData[i];
+ }
+
+ maData.clear();
+}
+
+//-------------------------------------------------------------------------
+void SortedEntryList::Insert( SortListData *pEntry, long nPos )
+{
+ if ( nPos < (long) maData.size() )
+ maData.insert( maData.begin() + nPos, pEntry );
+ else
+ maData.push_back( pEntry );
+}
+
+//-------------------------------------------------------------------------
+SortListData* SortedEntryList::Remove( long nPos )
+{
+ SortListData *pData;
+
+ if ( nPos < (long) maData.size() )
+ {
+ pData = maData[ nPos ];
+ maData.erase( maData.begin() + nPos );
+ }
+ else
+ pData = NULL;
+
+ return pData;
+}
+
+//-------------------------------------------------------------------------
+SortListData* SortedEntryList::GetData( long nPos )
+{
+ SortListData *pData;
+
+ if ( nPos < (long) maData.size() )
+ pData = maData[ nPos ];
+ else
+ pData = NULL;
+
+ return pData;
+}
+
+//-------------------------------------------------------------------------
+long SortedEntryList::operator [] ( long nPos ) const
+{
+ SortListData *pData;
+
+ if ( nPos < (long) maData.size() )
+ pData = maData[ nPos ];
+ else
+ pData = NULL;
+
+ if ( pData )
+ if ( ! pData->mbModified )
+ return pData->mnCurPos;
+ else
+ {
+ OSL_ENSURE( sal_False, "SortedEntryList: Can't get value for modified entry!");
+ return 0;
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "SortedEntryList: invalid pos!");
+ return 0;
+ }
+}
+
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+void SimpleList::Remove( sal_uInt32 nPos )
+{
+ if ( nPos < (sal_uInt32) maData.size() )
+ {
+ maData.erase( maData.begin() + nPos );
+ }
+}
+
+//-------------------------------------------------------------------------
+void SimpleList::Remove( void* pData )
+{
+ sal_Bool bFound = sal_False;
+ sal_uInt32 i;
+
+ for ( i = 0; i < (sal_uInt32) maData.size(); i++ )
+ {
+ if ( maData[ i ] == pData )
+ {
+ bFound = sal_True;
+ break;
+ }
+ }
+
+ if ( bFound )
+ maData.erase( maData.begin() + i );
+}
+
+//-------------------------------------------------------------------------
+void SimpleList::Insert( void* pData, sal_uInt32 nPos )
+{
+ if ( nPos < (sal_uInt32) maData.size() )
+ maData.insert( maData.begin() + nPos, pData );
+ else
+ maData.push_back( pData );
+}
+
+//-------------------------------------------------------------------------
+void* SimpleList::GetObject( sal_uInt32 nPos ) const
+{
+ if ( nPos < (sal_uInt32) maData.size() )
+ return maData[ nPos ];
+ else
+ return NULL;
+}
+
+//-------------------------------------------------------------------------
+void SimpleList::Replace( void* pData, sal_uInt32 nPos )
+{
+ if ( nPos < (sal_uInt32) maData.size() )
+ maData[ nPos ] = pData;
+}
+
+//-------------------------------------------------------------------------
+//
+// class SRSPropertySetInfo.
+//
+//-------------------------------------------------------------------------
+
+SRSPropertySetInfo::SRSPropertySetInfo()
+{
+ maProps[0].Name = OUString::createFromAscii( "RowCount" );
+ maProps[0].Handle = -1;
+ maProps[0].Type = ::getCppuType( (const OUString*) NULL );
+ maProps[0].Attributes = -1;
+
+ maProps[1].Name = OUString::createFromAscii( "IsRowCountFinal" );
+ maProps[1].Handle = -1;
+ maProps[1].Type = ::getBooleanCppuType();
+ maProps[1].Attributes = -1;
+}
+
+//-------------------------------------------------------------------------
+SRSPropertySetInfo::~SRSPropertySetInfo()
+{}
+
+//-------------------------------------------------------------------------
+// XInterface methods.
+//-------------------------------------------------------------------------
+
+XINTERFACE_IMPL_2( SRSPropertySetInfo,
+ XTypeProvider,
+ XPropertySetInfo );
+
+//-------------------------------------------------------------------------
+// XTypeProvider methods.
+//-------------------------------------------------------------------------
+
+XTYPEPROVIDER_IMPL_2( SRSPropertySetInfo,
+ XTypeProvider,
+ XPropertySetInfo );
+
+//-------------------------------------------------------------------------
+// XPropertySetInfo methods.
+//-------------------------------------------------------------------------
+Sequence< Property > SAL_CALL
+SRSPropertySetInfo::getProperties() throw( RuntimeException )
+{
+ return Sequence < Property > ( maProps, 2 );
+}
+
+//-------------------------------------------------------------------------
+Property SAL_CALL
+SRSPropertySetInfo::getPropertyByName( const OUString& Name )
+ throw( UnknownPropertyException, RuntimeException )
+{
+ if ( Name.compareToAscii( "RowCount" ) == 0 )
+ return maProps[0];
+ else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 )
+ return maProps[1];
+ else
+ throw UnknownPropertyException();
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL
+SRSPropertySetInfo::hasPropertyByName( const OUString& Name )
+ throw( RuntimeException )
+{
+ if ( Name.compareToAscii( "RowCount" ) == 0 )
+ return sal_True;
+ else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 )
+ return sal_True;
+ else
+ return sal_False;
+}
+
diff --git a/ucb/source/sorter/sortresult.hxx b/ucb/source/sorter/sortresult.hxx
new file mode 100644
index 000000000000..3817152f3d6c
--- /dev/null
+++ b/ucb/source/sorter/sortresult.hxx
@@ -0,0 +1,455 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SORTRESULT_HXX
+#define _SORTRESULT_HXX
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/sdbc/XCloseable.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaData.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
+#include <com/sun/star/ucb/ListAction.hpp>
+#include <cppuhelper/weak.hxx>
+#include <osl/mutex.hxx>
+
+#include <deque>
+#include <ucbhelper/macros.hxx>
+
+namespace cppu {
+ class OInterfaceContainerHelper;
+}
+
+//-----------------------------------------------------------------------------
+struct SortInfo;
+struct SortListData;
+class SRSPropertySetInfo;
+class PropertyChangeListeners_Impl;
+
+//-----------------------------------------------------------------------------
+class SortedEntryList
+{
+ std::deque < SortListData* > maData;
+
+public:
+ SortedEntryList(){}
+ ~SortedEntryList(){ Clear(); }
+
+ sal_uInt32 Count() const { return (sal_uInt32) maData.size(); }
+
+ void Clear();
+ void Insert( SortListData *pEntry, long nPos );
+ SortListData* Remove( long nPos );
+ SortListData* GetData( long nPos );
+
+ long operator [] ( long nPos ) const;
+};
+
+//-----------------------------------------------------------------------------
+#define LISTACTION com::sun::star::ucb::ListAction
+
+class EventList
+{
+ std::deque < LISTACTION* > maData;
+
+public:
+ EventList(){}
+ ~EventList(){ Clear(); }
+
+ sal_uInt32 Count() { return (sal_uInt32) maData.size(); }
+
+ void AddEvent( long nType, long nPos, long nCount );
+ void Insert( LISTACTION *pAction ) { maData.push_back( pAction ); }
+ void Clear();
+ LISTACTION* GetAction( long nIndex ) { return maData[ nIndex ]; }
+};
+
+//-----------------------------------------------------------------------------
+
+class SimpleList
+{
+ std::deque < void* > maData;
+
+public:
+ SimpleList(){}
+ ~SimpleList(){ Clear(); }
+
+ sal_uInt32 Count() { return (sal_uInt32) maData.size(); }
+ void Clear() { maData.clear(); }
+
+ void Remove( sal_uInt32 nPos );
+ void Remove( void* pData );
+
+ void Append( void* pData )
+ { maData.push_back( pData ); }
+ void Insert( void* pData, sal_uInt32 nPos );
+ void* GetObject( sal_uInt32 nPos ) const;
+ void Replace( void* pData, sal_uInt32 nPos );
+};
+
+//-----------------------------------------------------------------------------
+
+#define PROPERTYCHANGEEVENT com::sun::star::beans::PropertyChangeEvent
+#define RUNTIME_EXCEPTION com::sun::star::uno::RuntimeException
+#define REFERENCE com::sun::star::uno::Reference
+#define SEQUENCE com::sun::star::uno::Sequence
+#define XEVENTLISTENER com::sun::star::lang::XEventListener
+#define XRESULTSET com::sun::star::sdbc::XResultSet
+#define SQLEXCEPTION com::sun::star::sdbc::SQLException
+#define XRESULTSETMETADATA com::sun::star::sdbc::XResultSetMetaData
+#define NUMBERED_SORTINGINFO com::sun::star::ucb::NumberedSortingInfo
+#define XANYCOMPAREFACTORY com::sun::star::ucb::XAnyCompareFactory
+
+#define RESULTSET_SERVICE_NAME "com.sun.star.ucb.SortedResultSet"
+
+//-----------------------------------------------------------------------------
+
+class SortedResultSet:
+ public cppu::OWeakObject,
+ public com::sun::star::lang::XTypeProvider,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::lang::XComponent,
+ public com::sun::star::ucb::XContentAccess,
+ public XRESULTSET,
+ public com::sun::star::sdbc::XRow,
+ public com::sun::star::sdbc::XCloseable,
+ public com::sun::star::sdbc::XResultSetMetaDataSupplier,
+ public com::sun::star::beans::XPropertySet
+{
+ cppu::OInterfaceContainerHelper *mpDisposeEventListeners;
+ PropertyChangeListeners_Impl *mpPropChangeListeners;
+ PropertyChangeListeners_Impl *mpVetoChangeListeners;
+
+ REFERENCE < XRESULTSET > mxOriginal;
+ REFERENCE < XRESULTSET > mxOther;
+
+ SRSPropertySetInfo* mpPropSetInfo;
+ SortInfo* mpSortInfo;
+ osl::Mutex maMutex;
+ SortedEntryList maS2O; // maps the sorted entries to the original ones
+ SimpleList maO2S; // maps the original Entries to the sorted ones
+ SimpleList maModList; // keeps track of modified entries
+ long mnLastSort; // index of the last sorted entry;
+ long mnCurEntry; // index of the current entry
+ long mnCount; // total count of the elements
+ sal_Bool mbIsCopy;
+
+
+private:
+
+ long FindPos( SortListData *pEntry, long nStart, long nEnd )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ long Compare( SortListData *pOne,
+ SortListData *pTwo )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ void BuildSortInfo( REFERENCE< XRESULTSET > aResult,
+ const SEQUENCE < NUMBERED_SORTINGINFO > &xSortInfo,
+ const REFERENCE< XANYCOMPAREFACTORY > &xCompFac );
+ long CompareImpl( REFERENCE < XRESULTSET > xResultOne,
+ REFERENCE < XRESULTSET > xResultTwo,
+ long nIndexOne, long nIndexTwo,
+ SortInfo* pSortInfo )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ long CompareImpl( REFERENCE < XRESULTSET > xResultOne,
+ REFERENCE < XRESULTSET > xResultTwo,
+ long nIndexOne, long nIndexTwo )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ void PropertyChanged( const PROPERTYCHANGEEVENT& rEvt );
+
+public:
+ SortedResultSet( REFERENCE< XRESULTSET > aResult );
+ ~SortedResultSet();
+
+ const SortedEntryList* GetS2OList() const { return &maS2O; }
+ const SimpleList* GetO2SList() const { return &maO2S; }
+ REFERENCE < XRESULTSET > GetResultSet() const { return mxOriginal; }
+ SortInfo* GetSortInfo() const { return mpSortInfo; }
+ long GetCount() const { return mnCount; }
+
+ void CopyData( SortedResultSet* pSource );
+ void Initialize( const SEQUENCE < NUMBERED_SORTINGINFO > &xSortInfo,
+ const REFERENCE< XANYCOMPAREFACTORY > &xCompFac );
+ void CheckProperties( long nOldCount, sal_Bool bWasFinal );
+
+ void InsertNew( long nPos, long nCount );
+ void SetChanged( long nPos, long nCount );
+ void Remove( long nPos, long nCount, EventList *pList );
+ void Move( long nPos, long nCount, long nOffset );
+
+ void ResortModified( EventList* pList );
+ void ResortNew( EventList* pList );
+
+ // XInterface
+ XINTERFACE_DECL()
+
+ // XTypeProvider
+ XTYPEPROVIDER_DECL()
+
+ // XServiceInfo
+ XSERVICEINFO_NOFACTORY_DECL()
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose() throw( RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ addEventListener( const REFERENCE< XEVENTLISTENER >& Listener )
+ throw( RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ removeEventListener( const REFERENCE< XEVENTLISTENER >& Listener )
+ throw( RUNTIME_EXCEPTION );
+
+ // XContentAccess
+ virtual rtl::OUString SAL_CALL
+ queryContentIdentifierString()
+ throw( RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::ucb::XContentIdentifier > SAL_CALL
+ queryContentIdentifier()
+ throw( RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::ucb::XContent > SAL_CALL
+ queryContent()
+ throw( RUNTIME_EXCEPTION );
+
+ // XResultSet
+ virtual sal_Bool SAL_CALL
+ next()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ isBeforeFirst()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ isAfterLast()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ isFirst()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ isLast()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual void SAL_CALL
+ beforeFirst()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual void SAL_CALL
+ afterLast()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ first()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ last()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Int32 SAL_CALL
+ getRow()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ absolute( sal_Int32 row )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ relative( sal_Int32 rows )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ previous()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual void SAL_CALL
+ refreshRow()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ rowUpdated()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ rowInserted()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual sal_Bool SAL_CALL
+ rowDeleted()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::uno::XInterface > SAL_CALL
+ getStatement()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ // XRow
+ virtual sal_Bool SAL_CALL
+ wasNull() throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual rtl::OUString SAL_CALL
+ getString( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual sal_Bool SAL_CALL
+ getBoolean( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual sal_Int8 SAL_CALL
+ getByte( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual sal_Int16 SAL_CALL
+ getShort( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual sal_Int32 SAL_CALL
+ getInt( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual sal_Int64 SAL_CALL
+ getLong( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual float SAL_CALL
+ getFloat( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual double SAL_CALL
+ getDouble( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
+ getBytes( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual com::sun::star::util::Date SAL_CALL
+ getDate( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual com::sun::star::util::Time SAL_CALL
+ getTime( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual com::sun::star::util::DateTime SAL_CALL
+ getTimestamp( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual REFERENCE<
+ com::sun::star::io::XInputStream > SAL_CALL
+ getBinaryStream( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual REFERENCE<
+ com::sun::star::io::XInputStream > SAL_CALL
+ getCharacterStream( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getObject( sal_Int32 columnIndex,
+ const REFERENCE<
+ com::sun::star::container::XNameAccess >& typeMap )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::sdbc::XRef > SAL_CALL
+ getRef( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::sdbc::XBlob > SAL_CALL
+ getBlob( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::sdbc::XClob > SAL_CALL
+ getClob( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+ virtual REFERENCE<
+ com::sun::star::sdbc::XArray > SAL_CALL
+ getArray( sal_Int32 columnIndex )
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ // XCloseable
+ virtual void SAL_CALL
+ close()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+ // XResultSetMetaDataSupplier
+ virtual REFERENCE< XRESULTSETMETADATA > SAL_CALL
+ getMetaData()
+ throw( SQLEXCEPTION, RUNTIME_EXCEPTION );
+
+
+ // XPropertySet
+ virtual REFERENCE<
+ com::sun::star::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo()
+ throw( RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ setPropertyValue( const rtl::OUString& PropertyName,
+ const com::sun::star::uno::Any& Value )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::beans::PropertyVetoException,
+ com::sun::star::lang::IllegalArgumentException,
+ com::sun::star::lang::WrappedTargetException,
+ RUNTIME_EXCEPTION );
+
+ virtual com::sun::star::uno::Any SAL_CALL
+ getPropertyValue( const rtl::OUString& PropertyName )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ addPropertyChangeListener( const rtl::OUString& PropertyName,
+ const REFERENCE<
+ com::sun::star::beans::XPropertyChangeListener >& Listener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ removePropertyChangeListener( const rtl::OUString& PropertyName,
+ const REFERENCE<
+ com::sun::star::beans::XPropertyChangeListener >& Listener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ addVetoableChangeListener( const rtl::OUString& PropertyName,
+ const REFERENCE<
+ com::sun::star::beans::XVetoableChangeListener >& Listener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ RUNTIME_EXCEPTION );
+
+ virtual void SAL_CALL
+ removeVetoableChangeListener( const rtl::OUString& PropertyName,
+ const REFERENCE<
+ com::sun::star::beans::XVetoableChangeListener >& aListener )
+ throw( com::sun::star::beans::UnknownPropertyException,
+ com::sun::star::lang::WrappedTargetException,
+ RUNTIME_EXCEPTION );
+};
+
+#endif
+
diff --git a/ucb/source/sorter/srtrs.xml b/ucb/source/sorter/srtrs.xml
new file mode 100644
index 000000000000..51626a1e6acc
--- /dev/null
+++ b/ucb/source/sorter/srtrs.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name>
+ srtrs
+ </module-name>
+
+ <component-description>
+ <author>
+ Dirk Voelzke
+ </author>
+ <name>
+ com.sun.star.comp.ucb.SortedDynamicResultSetFactory
+ </name>
+ <description>
+ This component implements a factory for sorted Content Resultsets.
+ It can be used to sort resultsets obtained from UCB folder contents.
+ </description>
+ <loader-name>
+ com.sun.star.loader.SharedLibrary
+ </loader-name>
+ <language>
+ c++
+ </language>
+ <status value="final"/>
+ <supported-service>
+ com.sun.star.ucb.SortedDynamicResultSetFactory
+ </supported-service>
+
+ <service-dependency>
+ com.sun.star.ucb.CachedDynamicResultSetStubFactory
+ </service-dependency>
+ </component-description>
+
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+
+ <type> com.sun.star.beans.XPropertySet </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.sdbc.DataType </type>
+ <type> com.sun.star.sdbc.XCloseable </type>
+ <type> com.sun.star.sdbc.XResultSet </type>
+ <type> com.sun.star.sdbc.XResultSetMetaDataSupplier </type>
+ <type> com.sun.star.sdbc.XRow </type>
+ <type> com.sun.star.ucb.ContentResultSetCapability </type>
+ <type> com.sun.star.ucb.ListActionType </type>
+ <type> com.sun.star.ucb.NumberedSortingInfo </type>
+ <type> com.sun.star.ucb.WelcomeDynamicResultSetStruct </type>
+ <type> com.sun.star.ucb.XCachedDynamicResultSetStubFactory </type>
+ <type> com.sun.star.ucb.XContentAccess </type>
+ <type> com.sun.star.ucb.XDynamicResultSet </type>
+ <type> com.sun.star.ucb.XSortedDynamicResultSetFactory </type>
+ <type> com.sun.star.ucb.XSourceInitialization </type>
+ <type> com.sun.star.uno.XWeak </type>
+</module-description>
diff --git a/ucb/source/sorter/srtrs1.component b/ucb/source/sorter/srtrs1.component
new file mode 100644
index 000000000000..c32705160c0f
--- /dev/null
+++ b/ucb/source/sorter/srtrs1.component
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.ucb.SortedDynamicResultSetFactory">
+ <service name="com.sun.star.ucb.SortedDynamicResultSetFactory"/>
+ </implementation>
+</component>