xref: /aoo41x/main/ucb/source/ucp/file/filrset.cxx (revision cdf0e10c)
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