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