xref: /trunk/main/ucb/source/ucp/file/filrset.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_ucb.hxx"
30 #include <com/sun/star/ucb/WelcomeDynamicResultSetStruct.hpp>
31 #include "filid.hxx"
32 #include "shell.hxx"
33 #include "filprp.hxx"
34 #include "filrset.hxx"
35 #include <com/sun/star/ucb/OpenMode.hpp>
36 #include "prov.hxx"
37 #include <com/sun/star/uno/Reference.h>
38 
39 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #endif
42 #include <com/sun/star/ucb/ListActionType.hpp>
43 #include <com/sun/star/ucb/XSourceInitialization.hpp>
44 #include <com/sun/star/ucb/XCachedDynamicResultSetStubFactory.hpp>
45 #include <ucbhelper/resultsetmetadata.hxx>
46 
47 using namespace fileaccess;
48 using namespace com::sun::star;
49 
50 XResultSet_impl::XResultSet_impl(
51     shell* pMyShell,
52     const rtl::OUString& aUnqPath,
53     sal_Int32 OpenMode,
54     const uno::Sequence< beans::Property >& seq,
55     const uno::Sequence< ucb::NumberedSortingInfo >& seqSort )
56     : m_pMyShell( pMyShell ),
57       m_xProvider( pMyShell->m_pProvider ),
58       m_nRow( -1 ),
59       m_nOpenMode( OpenMode ),
60       m_bRowCountFinal( false ),
61       m_aBaseDirectory( aUnqPath ),
62       m_aFolder( aUnqPath ),
63       m_sProperty( seq ),
64       m_sSortingInfo( seqSort ),
65       m_pDisposeEventListeners( 0 ),
66       m_pRowCountListeners( 0 ),
67       m_pIsFinalListeners( 0 ),
68       m_bStatic( false ),
69       m_nErrorCode( TASKHANDLER_NO_ERROR ),
70       m_nMinorErrorCode( TASKHANDLER_NO_ERROR )
71 {
72     osl::FileBase::RC err = m_aFolder.open();
73     if(  err != osl::FileBase::E_None )
74     {
75         m_nIsOpen = false;
76         m_aFolder.close();
77 
78         m_nErrorCode = TASKHANDLING_OPEN_FOR_DIRECTORYLISTING;
79         m_nMinorErrorCode = err;
80     }
81     else
82         m_nIsOpen = true;
83 
84     m_pMyShell->registerNotifier( m_aBaseDirectory,this );
85 }
86 
87 
88 XResultSet_impl::~XResultSet_impl()
89 {
90     m_pMyShell->deregisterNotifier( m_aBaseDirectory,this );
91 
92     if( m_nIsOpen )
93         m_aFolder.close();
94 
95     delete m_pDisposeEventListeners;
96     delete m_pRowCountListeners;
97     delete m_pIsFinalListeners;
98 }
99 
100 
101 
102 sal_Int32 SAL_CALL XResultSet_impl::CtorSuccess()
103 {
104     return m_nErrorCode;
105 }
106 
107 
108 
109 sal_Int32 SAL_CALL XResultSet_impl::getMinorError()
110 {
111     return m_nMinorErrorCode;
112 }
113 
114 
115 void SAL_CALL
116 XResultSet_impl::acquire(
117     void )
118     throw()
119 {
120     OWeakObject::acquire();
121 }
122 
123 
124 void SAL_CALL
125 XResultSet_impl::release(
126     void )
127     throw()
128 {
129     OWeakObject::release();
130 }
131 
132 
133 
134 uno::Any SAL_CALL
135 XResultSet_impl::queryInterface(
136     const uno::Type& rType )
137     throw( uno::RuntimeException )
138 {
139     uno::Any aRet = cppu::queryInterface(
140         rType,
141         SAL_STATIC_CAST( lang::XComponent*, this),
142         SAL_STATIC_CAST( lang::XTypeProvider*, this),
143         SAL_STATIC_CAST( lang::XEventListener*, this),
144         SAL_STATIC_CAST( sdbc::XRow*, this),
145         SAL_STATIC_CAST( sdbc::XResultSet*, this),
146         SAL_STATIC_CAST( sdbc::XCloseable*, this),
147         SAL_STATIC_CAST( sdbc::XResultSetMetaDataSupplier*, this),
148         SAL_STATIC_CAST( beans::XPropertySet*, this ),
149         SAL_STATIC_CAST( ucb::XContentAccess*, this),
150         SAL_STATIC_CAST( ucb::XDynamicResultSet*,this) );
151     return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
152 }
153 
154 
155 void SAL_CALL
156 XResultSet_impl::disposing( const lang::EventObject& )
157     throw( uno::RuntimeException )
158 {
159     // To do, but what
160 }
161 
162 
163 XTYPEPROVIDER_IMPL_10( XResultSet_impl,
164                        lang::XTypeProvider,
165                        lang::XTypeProvider,
166                        lang::XEventListener,
167                        sdbc::XRow,
168                        sdbc::XResultSet,
169                        XDynamicResultSet,
170                        sdbc::XCloseable,
171                        sdbc::XResultSetMetaDataSupplier,
172                        beans::XPropertySet,
173                        ucb::XContentAccess )
174 
175 
176 void SAL_CALL
177 XResultSet_impl::addEventListener(
178     const uno::Reference< lang::XEventListener >& Listener )
179     throw( uno::RuntimeException )
180 {
181     osl::MutexGuard aGuard( m_aMutex );
182 
183     if ( ! m_pDisposeEventListeners )
184         m_pDisposeEventListeners =
185             new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
186 
187     m_pDisposeEventListeners->addInterface( Listener );
188 }
189 
190 
191 void SAL_CALL
192 XResultSet_impl::removeEventListener(
193     const uno::Reference< lang::XEventListener >& Listener )
194     throw( uno::RuntimeException )
195 {
196     osl::MutexGuard aGuard( m_aMutex );
197 
198     if ( m_pDisposeEventListeners )
199         m_pDisposeEventListeners->removeInterface( Listener );
200 }
201 
202 
203 
204 void SAL_CALL
205 XResultSet_impl::dispose()
206     throw( uno::RuntimeException )
207 {
208     osl::MutexGuard aGuard( m_aMutex );
209 
210     lang::EventObject aEvt;
211     aEvt.Source = static_cast< lang::XComponent * >( this );
212 
213     if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
214     {
215         m_pDisposeEventListeners->disposeAndClear( aEvt );
216     }
217     if( m_pRowCountListeners && m_pRowCountListeners->getLength() )
218     {
219         m_pRowCountListeners->disposeAndClear( aEvt );
220     }
221     if( m_pIsFinalListeners && m_pIsFinalListeners->getLength() )
222     {
223         m_pIsFinalListeners->disposeAndClear( aEvt );
224     }
225 }
226 
227 
228 
229 void XResultSet_impl::rowCountChanged()
230 {
231     sal_Int32 aOldValue,aNewValue;
232     uno::Sequence< uno::Reference< uno::XInterface > > seq;
233     {
234         osl::MutexGuard aGuard( m_aMutex );
235         if( m_pRowCountListeners )
236             seq = m_pRowCountListeners->getElements();
237         aNewValue = m_aItems.size();
238         aOldValue = aNewValue-1;
239     }
240     beans::PropertyChangeEvent aEv;
241     aEv.PropertyName = rtl::OUString::createFromAscii( "RowCount" );
242     aEv.Further = false;
243     aEv.PropertyHandle = -1;
244     aEv.OldValue <<= aOldValue;
245     aEv.NewValue <<= aNewValue;
246     for( sal_Int32 i = 0; i < seq.getLength(); ++i )
247     {
248         uno::Reference< beans::XPropertyChangeListener > listener(
249             seq[i], uno::UNO_QUERY );
250         if( listener.is() )
251             listener->propertyChange( aEv );
252     }
253 }
254 
255 
256 void XResultSet_impl::isFinalChanged()
257 {
258     uno::Sequence< uno::Reference< XInterface > > seq;
259     {
260         osl::MutexGuard aGuard( m_aMutex );
261         if( m_pIsFinalListeners )
262             seq = m_pIsFinalListeners->getElements();
263         m_bRowCountFinal = true;
264     }
265     beans::PropertyChangeEvent aEv;
266     aEv.PropertyName = rtl::OUString::createFromAscii( "IsRowCountFinal" );
267     aEv.Further = false;
268     aEv.PropertyHandle = -1;
269     sal_Bool fval = false;
270     sal_Bool tval = true;
271     aEv.OldValue <<= fval;
272     aEv.NewValue <<= tval;
273     for( sal_Int32 i = 0; i < seq.getLength(); ++i )
274     {
275         uno::Reference< beans::XPropertyChangeListener > listener(
276             seq[i], uno::UNO_QUERY );
277         if( listener.is() )
278             listener->propertyChange( aEv );
279     }
280 }
281 
282 
283 sal_Bool SAL_CALL
284 XResultSet_impl::OneMore(
285     void )
286     throw( sdbc::SQLException,
287            uno::RuntimeException )
288 {
289     if( ! m_nIsOpen )
290         return false;
291 
292     osl::FileBase::RC err;
293     sal_Bool IsRegular;
294     rtl::OUString aUnqPath;
295     osl::DirectoryItem  m_aDirIte;
296     uno::Reference< sdbc::XRow > aRow;
297 
298     while( true )
299     {
300         err = m_aFolder.getNextItem( m_aDirIte );
301 
302         if( err == osl::FileBase::E_NOENT || err == osl::FileBase::E_INVAL )
303         {
304             m_aFolder.close();
305             isFinalChanged();
306             return ( m_nIsOpen = false );
307         }
308         else if( err == osl::FileBase::E_None )
309         {
310             aRow = m_pMyShell->getv(
311                 this, m_sProperty, m_aDirIte, aUnqPath, IsRegular );
312 
313             if( m_nOpenMode == ucb::OpenMode::DOCUMENTS && IsRegular )
314             {
315                 osl::MutexGuard aGuard( m_aMutex );
316                 m_aItems.push_back( aRow );
317                 m_aIdents.push_back(
318                     uno::Reference< ucb::XContentIdentifier >() );
319                 m_aUnqPath.push_back( aUnqPath );
320                 rowCountChanged();
321                 return true;
322 
323             }
324             else if( m_nOpenMode == ucb::OpenMode::DOCUMENTS && ! IsRegular )
325             {
326                 continue;
327             }
328             else if( m_nOpenMode == ucb::OpenMode::FOLDERS && ! IsRegular )
329             {
330                 osl::MutexGuard aGuard( m_aMutex );
331                 m_aItems.push_back( aRow );
332                 m_aIdents.push_back(
333                     uno::Reference< ucb::XContentIdentifier >() );
334                 m_aUnqPath.push_back( aUnqPath );
335                 rowCountChanged();
336                 return true;
337             }
338             else if( m_nOpenMode == ucb::OpenMode::FOLDERS && IsRegular )
339             {
340                 continue;
341             }
342             else
343             {
344                 osl::MutexGuard aGuard( m_aMutex );
345                 m_aItems.push_back( aRow );
346                 m_aIdents.push_back(
347                     uno::Reference< ucb::XContentIdentifier >() );
348                 m_aUnqPath.push_back( aUnqPath );
349                 rowCountChanged();
350                 return true;
351             }
352         }
353         else  // error fetching anything
354         {
355             throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
356         }
357     }
358 }
359 
360 
361 
362 
363 
364 sal_Bool SAL_CALL
365 XResultSet_impl::next(
366     void )
367     throw( sdbc::SQLException,
368            uno::RuntimeException )
369 {
370     sal_Bool test;
371     if( ++m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) ) test = true;
372     else
373         test = OneMore();
374     return test;
375 }
376 
377 
378 sal_Bool SAL_CALL
379 XResultSet_impl::isBeforeFirst(
380     void )
381     throw( sdbc::SQLException,
382            uno::RuntimeException )
383 {
384     return m_nRow == -1;
385 }
386 
387 
388 sal_Bool SAL_CALL
389 XResultSet_impl::isAfterLast(
390     void )
391     throw( sdbc::SQLException,
392            uno::RuntimeException )
393 {
394     return m_nRow >= sal::static_int_cast<sal_Int32>(m_aItems.size());   // Cannot happen, if m_aFolder.isOpen()
395 }
396 
397 
398 sal_Bool SAL_CALL
399 XResultSet_impl::isFirst(
400     void )
401     throw( sdbc::SQLException,
402            uno::RuntimeException )
403 {
404     return m_nRow == 0;
405 }
406 
407 
408 sal_Bool SAL_CALL
409 XResultSet_impl::isLast(
410     void  )
411     throw( sdbc::SQLException,
412            uno::RuntimeException)
413 {
414     if( m_nRow ==  sal::static_int_cast<sal_Int32>(m_aItems.size()) - 1 )
415         return ! OneMore();
416     else
417         return false;
418 }
419 
420 
421 void SAL_CALL
422 XResultSet_impl::beforeFirst(
423     void  )
424     throw( sdbc::SQLException,
425            uno::RuntimeException)
426 {
427     m_nRow = -1;
428 }
429 
430 
431 void SAL_CALL
432 XResultSet_impl::afterLast(
433     void  )
434     throw( sdbc::SQLException,
435            uno::RuntimeException )
436 {
437     m_nRow = sal::static_int_cast<sal_Int32>(m_aItems.size());
438     while( OneMore() )
439         ++m_nRow;
440 }
441 
442 
443 sal_Bool SAL_CALL
444 XResultSet_impl::first(
445     void  )
446     throw( sdbc::SQLException,
447            uno::RuntimeException)
448 {
449     m_nRow = -1;
450     return next();
451 }
452 
453 
454 sal_Bool SAL_CALL
455 XResultSet_impl::last(
456     void  )
457     throw( sdbc::SQLException,
458            uno::RuntimeException )
459 {
460     m_nRow = sal::static_int_cast<sal_Int32>(m_aItems.size()) - 1;
461     while( OneMore() )
462         ++m_nRow;
463     return true;
464 }
465 
466 
467 sal_Int32 SAL_CALL
468 XResultSet_impl::getRow(
469     void )
470     throw( sdbc::SQLException,
471            uno::RuntimeException)
472 {
473     // Test, whether behind last row
474     if( -1 == m_nRow || m_nRow >= sal::static_int_cast<sal_Int32>(m_aItems.size()) )
475         return 0;
476     else
477         return m_nRow+1;
478 }
479 
480 
481 
482 sal_Bool SAL_CALL XResultSet_impl::absolute( sal_Int32 row )
483     throw( sdbc::SQLException, uno::RuntimeException)
484 {
485     if( row >= 0 )
486     {
487         m_nRow = row - 1;
488         if( row >= sal::static_int_cast<sal_Int32>(m_aItems.size()) )
489             while( row-- && OneMore() )
490                 ;
491     }
492     else
493     {
494         last();
495         m_nRow += ( row + 1 );
496         if( m_nRow < -1 )
497             m_nRow = -1;
498     }
499 
500     return 0<= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size());
501 }
502 
503 
504 
505 
506 sal_Bool SAL_CALL
507 XResultSet_impl::relative(
508     sal_Int32 row )
509     throw( sdbc::SQLException,
510            uno::RuntimeException)
511 {
512     if( isAfterLast() || isBeforeFirst() )
513         throw sdbc::SQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), ::rtl::OUString(), 0, uno::Any() );
514     if( row > 0 )
515         while( row-- ) next();
516     else if( row < 0 )
517         while( row++ && m_nRow > - 1 ) previous();
518 
519     return 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size());
520 }
521 
522 
523 
524 sal_Bool SAL_CALL
525 XResultSet_impl::previous(
526     void )
527     throw( sdbc::SQLException,
528            uno::RuntimeException)
529 {
530     if( m_nRow > sal::static_int_cast<sal_Int32>(m_aItems.size()) )
531         m_nRow = sal::static_int_cast<sal_Int32>(m_aItems.size());  // Correct Handling of afterLast
532     if( 0 <= m_nRow ) -- m_nRow;
533 
534     return 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size());
535 }
536 
537 
538 void SAL_CALL
539 XResultSet_impl::refreshRow(
540     void )
541     throw( sdbc::SQLException,
542            uno::RuntimeException)
543 {
544     // get the row from the filesystem
545     return;
546 }
547 
548 
549 sal_Bool SAL_CALL
550 XResultSet_impl::rowUpdated(
551     void )
552     throw( sdbc::SQLException,
553            uno::RuntimeException )
554 {
555     return false;
556 }
557 
558 sal_Bool SAL_CALL
559 XResultSet_impl::rowInserted(
560     void  )
561     throw( sdbc::SQLException,
562            uno::RuntimeException )
563 {
564     return false;
565 }
566 
567 sal_Bool SAL_CALL
568 XResultSet_impl::rowDeleted(
569     void  )
570     throw( sdbc::SQLException,
571            uno::RuntimeException )
572 {
573     return false;
574 }
575 
576 
577 uno::Reference< uno::XInterface > SAL_CALL
578 XResultSet_impl::getStatement(
579     void  )
580     throw( sdbc::SQLException,
581            uno::RuntimeException )
582 {
583     return uno::Reference< uno::XInterface >();
584 }
585 
586 
587 // XCloseable
588 
589 void SAL_CALL
590 XResultSet_impl::close(
591     void )
592     throw( sdbc::SQLException,
593            uno::RuntimeException)
594 {
595     if( m_nIsOpen )
596     {
597         m_aFolder.close();
598         isFinalChanged();
599         osl::MutexGuard aGuard( m_aMutex );
600         m_nIsOpen = false;
601     }
602 }
603 
604 
605 
606 rtl::OUString SAL_CALL
607 XResultSet_impl::queryContentIdentifierString(
608     void )
609     throw( uno::RuntimeException )
610 {
611     uno::Reference< ucb::XContentIdentifier > xContentId
612         = queryContentIdentifier();
613 
614     if( xContentId.is() )
615         return xContentId->getContentIdentifier();
616     else
617         return rtl::OUString();
618 }
619 
620 
621 uno::Reference< ucb::XContentIdentifier > SAL_CALL
622 XResultSet_impl::queryContentIdentifier(
623     void )
624     throw( uno::RuntimeException )
625 {
626     if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
627     {
628         if( ! m_aIdents[m_nRow].is() )
629         {
630             FileContentIdentifier* p
631                 = new FileContentIdentifier( m_pMyShell,
632                                              m_aUnqPath[  m_nRow ] );
633             m_aIdents[m_nRow] = uno::Reference< ucb::XContentIdentifier >(p);
634         }
635         return m_aIdents[m_nRow];
636     }
637     return uno::Reference< ucb::XContentIdentifier >();
638 }
639 
640 
641 uno::Reference< ucb::XContent > SAL_CALL
642 XResultSet_impl::queryContent(
643     void )
644     throw( uno::RuntimeException )
645 {
646     if( 0 <= m_nRow && m_nRow < sal::static_int_cast<sal_Int32>(m_aItems.size()) )
647         return m_pMyShell->m_pProvider->queryContent( queryContentIdentifier() );
648     else
649         return uno::Reference< ucb::XContent >();
650 }
651 
652 
653 // XDynamicResultSet
654 
655 
656 // virtual
657 uno::Reference< sdbc::XResultSet > SAL_CALL
658 XResultSet_impl::getStaticResultSet()
659     throw( ucb::ListenerAlreadySetException,
660            uno::RuntimeException )
661 {
662     osl::MutexGuard aGuard( m_aMutex );
663 
664     if ( m_xListener.is() )
665         throw ucb::ListenerAlreadySetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
666 
667     return uno::Reference< sdbc::XResultSet >( this );
668 }
669 
670 //=========================================================================
671 // virtual
672 void SAL_CALL
673 XResultSet_impl::setListener(
674     const uno::Reference< ucb::XDynamicResultSetListener >& Listener )
675     throw( ucb::ListenerAlreadySetException,
676            uno::RuntimeException )
677 {
678     osl::ClearableMutexGuard aGuard( m_aMutex );
679 
680     if ( m_xListener.is() )
681         throw ucb::ListenerAlreadySetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
682 
683     m_xListener = Listener;
684 
685     //////////////////////////////////////////////////////////////////////
686     // Create "welcome event" and send it to listener.
687     //////////////////////////////////////////////////////////////////////
688 
689     // Note: We only have the implementation for a static result set at the
690     //       moment (src590). The dynamic result sets passed to the listener
691     //       are a fake. This implementation will never call "notify" at the
692     //       listener to propagate any changes!!!
693 
694     uno::Any aInfo;
695     aInfo <<= ucb::WelcomeDynamicResultSetStruct( this, /* "old" */
696                                                   this /* "new" */ );
697 
698     uno::Sequence< ucb::ListAction > aActions( 1 );
699     aActions.getArray()[ 0 ] = ucb::ListAction( 0, // Position; not used
700                                                 0, // Count; not used
701                                                 ucb::ListActionType::WELCOME,
702                                                 aInfo );
703     aGuard.clear();
704 
705     Listener->notify(
706         ucb::ListEvent(
707             static_cast< cppu::OWeakObject * >( this ), aActions ) );
708 }
709 
710 //=========================================================================
711 // virtual
712 void SAL_CALL
713 XResultSet_impl::connectToCache(
714     const uno::Reference< ucb::XDynamicResultSet > & xCache )
715     throw( ucb::ListenerAlreadySetException,
716            ucb::AlreadyInitializedException,
717            ucb::ServiceNotFoundException,
718            uno::RuntimeException )
719 {
720     uno::Reference< lang::XMultiServiceFactory > mxSMgr
721         = m_pMyShell->m_xMultiServiceFactory;
722 
723     if( m_xListener.is() )
724         throw ucb::ListenerAlreadySetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
725     if( m_bStatic )
726         throw ucb::ListenerAlreadySetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
727 
728     uno::Reference< ucb::XSourceInitialization > xTarget(
729         xCache, uno::UNO_QUERY );
730     if( xTarget.is() && mxSMgr.is() )
731     {
732         uno::Reference< ucb::XCachedDynamicResultSetStubFactory > xStubFactory;
733         try
734         {
735             xStubFactory
736                 = uno::Reference< ucb::XCachedDynamicResultSetStubFactory >(
737                     mxSMgr->createInstance(
738                         rtl::OUString::createFromAscii(
739                             "com.sun.star.ucb.CachedDynamicResultSetStubFactory" ) ),
740                     uno::UNO_QUERY );
741         }
742         catch ( uno::Exception const & )
743         {
744         }
745 
746         if( xStubFactory.is() )
747         {
748             xStubFactory->connectToCache(
749                 this, xCache,m_sSortingInfo, NULL );
750             return;
751         }
752     }
753     throw ucb::ServiceNotFoundException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
754 }
755 
756 //=========================================================================
757 // virtual
758 sal_Int16 SAL_CALL
759 XResultSet_impl::getCapabilities()
760   throw( uno::RuntimeException )
761 {
762     // Never set ucb::ContentResultSetCapability::SORTED
763     //  - Underlying content cannot provide sorted data...
764     return 0;
765 }
766 
767 // XResultSetMetaDataSupplier
768 uno::Reference< sdbc::XResultSetMetaData > SAL_CALL
769 XResultSet_impl::getMetaData(
770     void )
771     throw( sdbc::SQLException,
772            uno::RuntimeException )
773 {
774     for ( sal_Int32 n = 0; n < m_sProperty.getLength(); ++n )
775     {
776         if ( m_sProperty.getConstArray()[ n ].Name.compareToAscii( "Title" )
777              == 0 )
778         {
779             // @@@ #82177# - Determine correct value!
780             sal_Bool bCaseSensitiveChildren = sal_False;
781 
782             std::vector< ::ucbhelper::ResultSetColumnData >
783                                     aColumnData( m_sProperty.getLength() );
784             aColumnData[ n ].isCaseSensitive = bCaseSensitiveChildren;
785 
786             ::ucbhelper::ResultSetMetaData* p =
787                 new ::ucbhelper::ResultSetMetaData(
788                     m_pMyShell->m_xMultiServiceFactory,
789                     m_sProperty,
790                     aColumnData );
791             return uno::Reference< sdbc::XResultSetMetaData >( p );
792         }
793     }
794 
795     ::ucbhelper::ResultSetMetaData* p =
796             new ::ucbhelper::ResultSetMetaData(
797                 m_pMyShell->m_xMultiServiceFactory, m_sProperty );
798     return uno::Reference< sdbc::XResultSetMetaData >( p );
799 }
800 
801 
802 
803 // XPropertySet
804 uno::Reference< beans::XPropertySetInfo > SAL_CALL
805 XResultSet_impl::getPropertySetInfo()
806     throw( uno::RuntimeException)
807 {
808 
809     uno::Sequence< beans::Property > seq(2);
810     seq[0].Name = rtl::OUString::createFromAscii( "RowCount" );
811     seq[0].Handle = -1;
812     seq[0].Type = getCppuType( static_cast< sal_Int32* >(0) );
813     seq[0].Attributes = beans::PropertyAttribute::READONLY;
814 
815     seq[0].Name = rtl::OUString::createFromAscii( "IsRowCountFinal" );
816     seq[0].Handle = -1;
817     seq[0].Type = getCppuType( static_cast< sal_Bool* >(0) );
818     seq[0].Attributes = beans::PropertyAttribute::READONLY;
819 
820     XPropertySetInfo_impl* p = new XPropertySetInfo_impl( m_pMyShell,
821                                                           seq );
822     return uno::Reference< beans::XPropertySetInfo > ( p );
823 }
824 
825 
826 
827 void SAL_CALL XResultSet_impl::setPropertyValue(
828     const rtl::OUString& aPropertyName, const uno::Any& )
829     throw( beans::UnknownPropertyException,
830            beans::PropertyVetoException,
831            lang::IllegalArgumentException,
832            lang::WrappedTargetException,
833            uno::RuntimeException)
834 {
835     if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ||
836         aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) )
837         return;
838     throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
839 }
840 
841 
842 uno::Any SAL_CALL XResultSet_impl::getPropertyValue(
843     const rtl::OUString& PropertyName )
844     throw( beans::UnknownPropertyException,
845            lang::WrappedTargetException,
846            uno::RuntimeException)
847 {
848     if( PropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) )
849     {
850         uno::Any aAny;
851         aAny <<= m_bRowCountFinal;
852         return aAny;
853     }
854     else if ( PropertyName == rtl::OUString::createFromAscii( "RowCount" ) )
855     {
856         uno::Any aAny;
857         sal_Int32 count = sal::static_int_cast<sal_Int32>(m_aItems.size());
858         aAny <<= count;
859         return aAny;
860     }
861     else
862         throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
863 }
864 
865 
866 void SAL_CALL XResultSet_impl::addPropertyChangeListener(
867     const rtl::OUString& aPropertyName,
868     const uno::Reference< beans::XPropertyChangeListener >& xListener )
869     throw( beans::UnknownPropertyException,
870            lang::WrappedTargetException,
871            uno::RuntimeException)
872 {
873     if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) )
874     {
875         osl::MutexGuard aGuard( m_aMutex );
876         if ( ! m_pIsFinalListeners )
877             m_pIsFinalListeners =
878                 new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
879 
880         m_pIsFinalListeners->addInterface( xListener );
881     }
882     else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) )
883     {
884         osl::MutexGuard aGuard( m_aMutex );
885         if ( ! m_pRowCountListeners )
886             m_pRowCountListeners =
887                 new cppu::OInterfaceContainerHelper( m_aEventListenerMutex );
888         m_pRowCountListeners->addInterface( xListener );
889     }
890     else
891         throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
892 }
893 
894 
895 void SAL_CALL XResultSet_impl::removePropertyChangeListener(
896     const rtl::OUString& aPropertyName,
897     const uno::Reference< beans::XPropertyChangeListener >& aListener )
898     throw( beans::UnknownPropertyException,
899            lang::WrappedTargetException,
900            uno::RuntimeException)
901 {
902     if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) &&
903         m_pIsFinalListeners )
904     {
905         osl::MutexGuard aGuard( m_aMutex );
906         m_pIsFinalListeners->removeInterface( aListener );
907     }
908     else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) &&
909               m_pRowCountListeners )
910     {
911         osl::MutexGuard aGuard( m_aMutex );
912 
913         m_pRowCountListeners->removeInterface( aListener );
914     }
915     else
916         throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
917 }
918 
919 void SAL_CALL XResultSet_impl::addVetoableChangeListener(
920     const rtl::OUString&,
921     const uno::Reference< beans::XVetoableChangeListener >& )
922     throw( beans::UnknownPropertyException,
923            lang::WrappedTargetException,
924            uno::RuntimeException)
925 {
926 }
927 
928 
929 void SAL_CALL XResultSet_impl::removeVetoableChangeListener(
930     const rtl::OUString&,
931     const uno::Reference< beans::XVetoableChangeListener >& )
932     throw( beans::UnknownPropertyException,
933            lang::WrappedTargetException,
934            uno::RuntimeException)
935 {
936 }
937