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