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_cacher.hxx"
26 
27 #include <cachedcontentresultsetstub.hxx>
28 #include <com/sun/star/sdbc/FetchDirection.hpp>
29 #include <com/sun/star/ucb/FetchError.hpp>
30 #include <osl/diagnose.h>
31 
32 using namespace com::sun::star::beans;
33 using namespace com::sun::star::lang;
34 using namespace com::sun::star::sdbc;
35 using namespace com::sun::star::ucb;
36 using namespace com::sun::star::uno;
37 using namespace com::sun::star::util;
38 using namespace cppu;
39 using namespace rtl;
40 
CachedContentResultSetStub(Reference<XResultSet> xOrigin)41 CachedContentResultSetStub::CachedContentResultSetStub( Reference< XResultSet > xOrigin	)
42 				: ContentResultSetWrapper( xOrigin )
43 				, m_nColumnCount( 0 )
44 				, m_bColumnCountCached( sal_False )
45 				, m_bNeedToPropagateFetchSize( sal_True )
46 				, m_bFirstFetchSizePropagationDone( sal_False )
47 				, m_nLastFetchSize( 1 )//this value is not important at all
48 				, m_bLastFetchDirection( sal_True )//this value is not important at all
49 				, m_aPropertyNameForFetchSize( OUString::createFromAscii( "FetchSize" ) )
50 				, m_aPropertyNameForFetchDirection( OUString::createFromAscii( "FetchDirection" ) )
51 {
52 	impl_init();
53 }
54 
~CachedContentResultSetStub()55 CachedContentResultSetStub::~CachedContentResultSetStub()
56 {
57 	impl_deinit();
58 }
59 
60 //--------------------------------------------------------------------------
61 // XInterface methods.
62 //--------------------------------------------------------------------------
XINTERFACE_COMMON_IMPL(CachedContentResultSetStub)63 XINTERFACE_COMMON_IMPL( CachedContentResultSetStub )
64 
65 Any SAL_CALL CachedContentResultSetStub
66 	::queryInterface( const Type&  rType )
67 	throw ( RuntimeException )
68 {
69 	//list all interfaces inclusive baseclasses of interfaces
70 
71 	Any aRet = ContentResultSetWrapper::queryInterface( rType );
72 	if( aRet.hasValue() )
73 		return aRet;
74 
75 	aRet = cppu::queryInterface( rType
76 				, static_cast< XTypeProvider* >( this )
77 				, static_cast< XServiceInfo* >( this )
78 				, static_cast< XFetchProvider* >( this )
79 				, static_cast< XFetchProviderForContentAccess* >( this )
80 				);
81 
82 	return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
83 }
84 
85 //--------------------------------------------------------------------------
86 // own methods.  ( inherited )
87 //--------------------------------------------------------------------------
88 
89 //virtual
90 void SAL_CALL CachedContentResultSetStub
impl_propertyChange(const PropertyChangeEvent & rEvt)91 	::impl_propertyChange( const PropertyChangeEvent& rEvt )
92 	throw( RuntimeException )
93 {
94 	impl_EnsureNotDisposed();
95 
96 	//don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
97 	//because it will ignore them anyway and we can save this remote calls
98 	if(	   rEvt.PropertyName == m_aPropertyNameForFetchSize
99 		|| rEvt.PropertyName == m_aPropertyNameForFetchDirection )
100 		return;
101 
102 	PropertyChangeEvent aEvt( rEvt );
103 	aEvt.Source = static_cast< XPropertySet * >( this );
104 	aEvt.Further = sal_False;
105 
106 	impl_notifyPropertyChangeListeners(	aEvt );
107 }
108 
109 
110 //virtual
111 void SAL_CALL CachedContentResultSetStub
impl_vetoableChange(const PropertyChangeEvent & rEvt)112 	::impl_vetoableChange( const PropertyChangeEvent& rEvt )
113 	throw( PropertyVetoException,
114 		   RuntimeException )
115 {
116 	impl_EnsureNotDisposed();
117 
118 	//don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
119 	//because it will ignore them anyway and we can save this remote calls
120 	if(	   rEvt.PropertyName == m_aPropertyNameForFetchSize
121 		|| rEvt.PropertyName == m_aPropertyNameForFetchDirection )
122 		return;
123 
124 	PropertyChangeEvent aEvt( rEvt );
125 	aEvt.Source = static_cast< XPropertySet * >( this );
126 	aEvt.Further = sal_False;
127 
128 	impl_notifyVetoableChangeListeners( aEvt );
129 }
130 
131 //--------------------------------------------------------------------------
132 // XTypeProvider methods.
133 //--------------------------------------------------------------------------
134 
XTYPEPROVIDER_COMMON_IMPL(CachedContentResultSetStub)135 XTYPEPROVIDER_COMMON_IMPL( CachedContentResultSetStub )
136 //list all interfaces exclusive baseclasses
137 Sequence< Type > SAL_CALL CachedContentResultSetStub
138 	::getTypes()
139 	throw( RuntimeException )
140 {
141 	static Sequence< Type >* pTypes = NULL;
142 	if( !pTypes )
143 	{
144 		osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
145 		if( !pTypes )
146 		{
147 			pTypes = new Sequence< Type >(13);
148 			(*pTypes)[0] = CPPU_TYPE_REF( XTypeProvider );
149 			(*pTypes)[1] = CPPU_TYPE_REF( XServiceInfo );
150 			(*pTypes)[2] = CPPU_TYPE_REF( XComponent );
151 			(*pTypes)[3] = CPPU_TYPE_REF( XCloseable );
152 			(*pTypes)[4] = CPPU_TYPE_REF( XResultSetMetaDataSupplier );
153 			(*pTypes)[5] = CPPU_TYPE_REF( XPropertySet );
154 			(*pTypes)[6] = CPPU_TYPE_REF( XPropertyChangeListener );
155 			(*pTypes)[7] = CPPU_TYPE_REF( XVetoableChangeListener );
156 			(*pTypes)[8] = CPPU_TYPE_REF( XResultSet );
157 			(*pTypes)[9] = CPPU_TYPE_REF( XContentAccess );
158 			(*pTypes)[10] = CPPU_TYPE_REF( XRow );
159 			(*pTypes)[11] = CPPU_TYPE_REF( XFetchProvider );
160 			(*pTypes)[12] = CPPU_TYPE_REF( XFetchProviderForContentAccess );
161 		}
162 	}
163 	return *pTypes;
164 	/*
165 	static cppu::OTypeCollection * pCollection = 0;
166 	if (!pCollection)
167 	{
168 		osl::MutexGuard aGuard(osl::Mutex::getGlobalMutex());
169 		if (!pCollection)
170 		{
171 			static cppu::OTypeCollection
172 				aTheCollection(
173 					getCppuType(
174 						static_cast< Reference< XTypeProvider >
175 						                 const * >(
176 							0)),
177 					getCppuType(
178 						static_cast< Reference< XServiceInfo >
179 						                 const * >(
180 							0)),
181 					getCppuType(
182 						static_cast< Reference< XComponent >
183 						                 const * >(
184 							0)),
185 					getCppuType(
186 						static_cast< Reference< XCloseable >
187 						                 const * >(
188 							0)),
189 					getCppuType(
190 						static_cast< Reference< XResultSetMetaDataSupplier >
191 						                 const * >(
192 							0)),
193 					getCppuType(
194 						static_cast< Reference< XPropertySet >
195 						                 const * >(
196 							0)),
197 					getCppuType(
198 						static_cast< Reference< XPropertyChangeListener >
199 						                 const * >(
200 							0)),
201 					getCppuType(
202 						static_cast< Reference< XVetoableChangeListener >
203 						                 const * >(
204 							0)),
205 					getCppuType(
206 						static_cast< Reference< XResultSet >
207 						                 const * >(
208 							0)),
209 					getCppuType(
210 						static_cast< Reference< XContentAccess >
211 						                 const * >(
212 							0)),
213 					getCppuType(
214 						static_cast< Reference< XRow >
215 						                 const * >(
216 							0)),
217 					getCppuType(
218 						static_cast< Reference< XFetchProvider >
219 						                 const * >(
220 							0)),
221 					getCppuType(
222 						static_cast< Reference< XFetchProviderForContentAccess >
223 						                 const * >(
224 							0))
225 							);
226 			pCollection = &aTheCollection;
227 		}
228 	}
229 	return pCollection->getTypes();
230 	*/
231 }
232 
233 //--------------------------------------------------------------------------
234 // XServiceInfo methods.
235 //--------------------------------------------------------------------------
236 
237 XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSetStub,
238 			 		   OUString::createFromAscii(
239 						"com.sun.star.comp.ucb.CachedContentResultSetStub" ),
240 			 		   OUString::createFromAscii(
241 						CACHED_CRS_STUB_SERVICE_NAME ) );
242 
243 //-----------------------------------------------------------------
244 // XFetchProvider methods.
245 //-----------------------------------------------------------------
246 
247 #define FETCH_XXX( impl_loadRow, loadInterface ) \
248 impl_EnsureNotDisposed(); \
249 if( !m_xResultSetOrigin.is() ) \
250 { \
251 	OSL_ENSURE( sal_False, "broadcaster was disposed already" ); \
252 	throw RuntimeException(); \
253 } \
254 impl_propagateFetchSizeAndDirection( nRowCount, bDirection ); \
255 FetchResult aRet; \
256 aRet.StartIndex = nRowStartPosition; \
257 aRet.Orientation = bDirection; \
258 aRet.FetchError = FetchError::SUCCESS; /*ENDOFDATA, EXCEPTION*/ \
259 sal_Int32 nOldOriginal_Pos = m_xResultSetOrigin->getRow(); \
260 if( impl_isForwardOnly() ) \
261 { \
262 	if( nOldOriginal_Pos != nRowStartPosition ) \
263 	{ \
264 		/*@todo*/ \
265 		aRet.FetchError = FetchError::EXCEPTION; \
266 		return aRet; \
267 	} \
268 	if( nRowCount != 1 ) \
269 		aRet.FetchError = FetchError::EXCEPTION; \
270  \
271 	aRet.Rows.realloc( 1 ); \
272  \
273 	try \
274 	{ \
275 		impl_loadRow( aRet.Rows[0], loadInterface ); \
276 	} \
277 	catch( SQLException& ) \
278 	{ \
279 		aRet.Rows.realloc( 0 ); \
280 		aRet.FetchError = FetchError::EXCEPTION; \
281 		return aRet; \
282 	} \
283 	return aRet; \
284 } \
285 aRet.Rows.realloc( nRowCount ); \
286 sal_Bool bOldOriginal_AfterLast = sal_False; \
287 if( !nOldOriginal_Pos ) \
288 	bOldOriginal_AfterLast = m_xResultSetOrigin->isAfterLast(); \
289 sal_Int32 nN = 1; \
290 sal_Bool bValidNewPos = sal_False; \
291 try \
292 { \
293 	try \
294 	{ \
295 		/*if( nOldOriginal_Pos != nRowStartPosition )*/ \
296 		bValidNewPos = m_xResultSetOrigin->absolute( nRowStartPosition ); \
297 	} \
298 	catch( SQLException& ) \
299 	{ \
300 		aRet.Rows.realloc( 0 ); \
301 		aRet.FetchError = FetchError::EXCEPTION; \
302 		return aRet; \
303 	} \
304 	if( !bValidNewPos ) \
305 	{ \
306 		aRet.Rows.realloc( 0 ); \
307 		aRet.FetchError = FetchError::EXCEPTION; \
308  \
309 		/*restore old position*/ \
310 		if( nOldOriginal_Pos ) \
311 			m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \
312 		else if( bOldOriginal_AfterLast ) \
313 			m_xResultSetOrigin->afterLast(); \
314 		else \
315 			m_xResultSetOrigin->beforeFirst(); \
316  \
317 		return aRet; \
318 	} \
319 	for( ; nN <= nRowCount; ) \
320 	{ \
321 		impl_loadRow( aRet.Rows[nN-1], loadInterface ); \
322 		nN++; \
323 		if( nN <= nRowCount ) \
324 		{ \
325 			if( bDirection ) \
326 			{ \
327 				if( !m_xResultSetOrigin->next() ) \
328 				{ \
329 					aRet.Rows.realloc( nN-1 ); \
330 					aRet.FetchError = FetchError::ENDOFDATA; \
331 					break; \
332 				} \
333 			} \
334 			else \
335 			{ \
336 				if( !m_xResultSetOrigin->previous() ) \
337 				{ \
338 					aRet.Rows.realloc( nN-1 ); \
339 					aRet.FetchError = FetchError::ENDOFDATA; \
340 					break; \
341 				} \
342 			} \
343 		} \
344 	} \
345 } \
346 catch( SQLException& ) \
347 { \
348 	aRet.Rows.realloc( nN-1 ); \
349 	aRet.FetchError = FetchError::EXCEPTION; \
350 } \
351 /*restore old position*/ \
352 if( nOldOriginal_Pos ) \
353 	m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \
354 else if( bOldOriginal_AfterLast ) \
355 	m_xResultSetOrigin->afterLast(); \
356 else \
357 	m_xResultSetOrigin->beforeFirst(); \
358 return aRet;
359 
360 FetchResult SAL_CALL CachedContentResultSetStub
fetch(sal_Int32 nRowStartPosition,sal_Int32 nRowCount,sal_Bool bDirection)361 	::fetch( sal_Int32 nRowStartPosition
362 	, sal_Int32 nRowCount, sal_Bool bDirection )
363 	throw( RuntimeException )
364 {
365 	impl_init_xRowOrigin();
366 	FETCH_XXX( impl_getCurrentRowContent, m_xRowOrigin );
367 }
368 
369 sal_Int32 SAL_CALL CachedContentResultSetStub
impl_getColumnCount()370 	::impl_getColumnCount()
371 {
372 	sal_Int32 nCount;
373 	sal_Bool bCached;
374 	{
375 		osl::Guard< osl::Mutex > aGuard( m_aMutex );
376 		nCount = m_nColumnCount;
377 		bCached = m_bColumnCountCached;
378 	}
379 	if( !bCached )
380 	{
381 		try
382 		{
383 			Reference< XResultSetMetaData > xMetaData = getMetaData();
384 			if( xMetaData.is() )
385 				nCount = xMetaData->getColumnCount();
386 		}
387 		catch( SQLException& )
388 		{
389 			OSL_ENSURE( sal_False, "couldn't determine the column count" );
390 			nCount = 0;
391 		}
392 	}
393 	osl::Guard< osl::Mutex > aGuard( m_aMutex );
394 	m_nColumnCount = nCount;
395 	m_bColumnCountCached = sal_True;
396 	return m_nColumnCount;
397 }
398 
399 void SAL_CALL CachedContentResultSetStub
impl_getCurrentRowContent(Any & rRowContent,Reference<XRow> xRow)400 	::impl_getCurrentRowContent( Any& rRowContent
401 		, Reference< XRow > xRow )
402 		throw ( SQLException, RuntimeException )
403 {
404 	sal_Int32 nCount = impl_getColumnCount();
405 
406 	Sequence< Any > aContent( nCount );
407 	for( sal_Int32 nN = 1; nN <= nCount; nN++ )
408 	{
409 		aContent[nN-1] = xRow->getObject( nN, NULL );
410 	}
411 
412 	rRowContent <<= aContent;
413 }
414 
415 void SAL_CALL CachedContentResultSetStub
impl_propagateFetchSizeAndDirection(sal_Int32 nFetchSize,sal_Bool bFetchDirection)416 	::impl_propagateFetchSizeAndDirection( sal_Int32 nFetchSize, sal_Bool bFetchDirection )
417 		throw ( RuntimeException )
418 {
419 	//this is done only for the case, that there is another CachedContentResultSet in the chain of underlying ResulSets
420 
421 	//we do not propagate the property 'FetchSize' or 'FetchDirection' via 'setPropertyValue' from the above CachedContentResultSet to save remote calls
422 
423 	//if the underlying ResultSet has a property FetchSize and FetchDirection,
424 	//we will set these properties, if the new given parameters are different from the last ones
425 
426 	if( !m_bNeedToPropagateFetchSize )
427 		return;
428 
429 	sal_Bool bNeedAction;
430 	sal_Int32 nLastSize;
431 	sal_Bool bLastDirection;
432 	sal_Bool bFirstPropagationDone;
433 	{
434 		osl::Guard< osl::Mutex > aGuard( m_aMutex );
435 		bNeedAction				= m_bNeedToPropagateFetchSize;
436 		nLastSize				= m_nLastFetchSize;
437 		bLastDirection			= m_bLastFetchDirection;
438 		bFirstPropagationDone	= m_bFirstFetchSizePropagationDone;
439 	}
440 	if( bNeedAction )
441 	{
442 		if( nLastSize == nFetchSize
443 			&& bLastDirection == bFetchDirection
444 			&& bFirstPropagationDone == sal_True )
445 			return;
446 
447 		if(!bFirstPropagationDone)
448 		{
449 			//check whether the properties 'FetchSize' and 'FetchDirection' do exist
450 
451 			Reference< XPropertySetInfo > xPropertySetInfo = getPropertySetInfo();
452 			sal_Bool bHasSize = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchSize );
453 			sal_Bool bHasDirection = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchDirection );
454 
455 			if(!bHasSize || !bHasDirection)
456 			{
457 				osl::Guard< osl::Mutex > aGuard( m_aMutex );
458 				m_bNeedToPropagateFetchSize = sal_False;
459 				return;
460 			}
461 		}
462 
463 		sal_Bool bSetSize		= ( nLastSize		!=nFetchSize		) || !bFirstPropagationDone;
464 		sal_Bool bSetDirection	= ( bLastDirection	!=bFetchDirection	) || !bFirstPropagationDone;
465 
466 		{
467 			osl::Guard< osl::Mutex > aGuard( m_aMutex );
468 			m_bFirstFetchSizePropagationDone = sal_True;
469 			m_nLastFetchSize		= nFetchSize;
470 			m_bLastFetchDirection	= bFetchDirection;
471 		}
472 
473 		if( bSetSize )
474 		{
475 			Any aValue;
476 			aValue <<= nFetchSize;
477 			try
478 			{
479 				setPropertyValue( m_aPropertyNameForFetchSize, aValue );
480 			}
481 			catch( com::sun::star::uno::Exception& ) {}
482 		}
483 		if( bSetDirection )
484 		{
485 			sal_Int32 nFetchDirection = FetchDirection::FORWARD;
486 			if( !bFetchDirection )
487 				nFetchDirection = FetchDirection::REVERSE;
488 			Any aValue;
489 			aValue <<= nFetchDirection;
490 			try
491 			{
492 				setPropertyValue( m_aPropertyNameForFetchDirection, aValue );
493 			}
494 			catch( com::sun::star::uno::Exception& ) {}
495 		}
496 
497 	}
498 }
499 
500 //-----------------------------------------------------------------
501 // XFetchProviderForContentAccess methods.
502 //-----------------------------------------------------------------
503 
504 void SAL_CALL CachedContentResultSetStub
impl_getCurrentContentIdentifierString(Any & rAny,Reference<XContentAccess> xContentAccess)505 	::impl_getCurrentContentIdentifierString( Any& rAny
506 		, Reference< XContentAccess > xContentAccess )
507 		throw ( RuntimeException )
508 {
509  	rAny <<= xContentAccess->queryContentIdentifierString();
510 }
511 
512 void SAL_CALL CachedContentResultSetStub
impl_getCurrentContentIdentifier(Any & rAny,Reference<XContentAccess> xContentAccess)513 	::impl_getCurrentContentIdentifier( Any& rAny
514 		, Reference< XContentAccess > xContentAccess )
515 		throw ( RuntimeException )
516 {
517  	rAny <<= xContentAccess->queryContentIdentifier();
518 }
519 
520 void SAL_CALL CachedContentResultSetStub
impl_getCurrentContent(Any & rAny,Reference<XContentAccess> xContentAccess)521 	::impl_getCurrentContent( Any& rAny
522 		, Reference< XContentAccess > xContentAccess )
523 		throw ( RuntimeException )
524 {
525  	rAny <<= xContentAccess->queryContent();
526 }
527 
528 //virtual
529 FetchResult SAL_CALL CachedContentResultSetStub
fetchContentIdentifierStrings(sal_Int32 nRowStartPosition,sal_Int32 nRowCount,sal_Bool bDirection)530 	::fetchContentIdentifierStrings( sal_Int32 nRowStartPosition
531 		, sal_Int32 nRowCount, sal_Bool bDirection )
532 		throw( com::sun::star::uno::RuntimeException )
533 {
534 	impl_init_xContentAccessOrigin();
535 	FETCH_XXX( impl_getCurrentContentIdentifierString, m_xContentAccessOrigin );
536 }
537 
538 //virtual
539 FetchResult SAL_CALL CachedContentResultSetStub
fetchContentIdentifiers(sal_Int32 nRowStartPosition,sal_Int32 nRowCount,sal_Bool bDirection)540 	::fetchContentIdentifiers( sal_Int32 nRowStartPosition
541 		, sal_Int32 nRowCount, sal_Bool bDirection )
542 		throw( com::sun::star::uno::RuntimeException )
543 {
544 	impl_init_xContentAccessOrigin();
545 	FETCH_XXX( impl_getCurrentContentIdentifier, m_xContentAccessOrigin );
546 }
547 
548 //virtual
549 FetchResult SAL_CALL CachedContentResultSetStub
fetchContents(sal_Int32 nRowStartPosition,sal_Int32 nRowCount,sal_Bool bDirection)550 	::fetchContents( sal_Int32 nRowStartPosition
551 		, sal_Int32 nRowCount, sal_Bool bDirection )
552 		throw( com::sun::star::uno::RuntimeException )
553 {
554 	impl_init_xContentAccessOrigin();
555 	FETCH_XXX( impl_getCurrentContent, m_xContentAccessOrigin );
556 }
557 
558 //--------------------------------------------------------------------------
559 //--------------------------------------------------------------------------
560 // class CachedContentResultSetStubFactory
561 //--------------------------------------------------------------------------
562 //--------------------------------------------------------------------------
563 
CachedContentResultSetStubFactory(const Reference<XMultiServiceFactory> & rSMgr)564 CachedContentResultSetStubFactory::CachedContentResultSetStubFactory(
565 		const Reference< XMultiServiceFactory > & rSMgr )
566 {
567 	m_xSMgr = rSMgr;
568 }
569 
~CachedContentResultSetStubFactory()570 CachedContentResultSetStubFactory::~CachedContentResultSetStubFactory()
571 {
572 }
573 
574 //--------------------------------------------------------------------------
575 // CachedContentResultSetStubFactory XInterface methods.
576 //--------------------------------------------------------------------------
577 
578 XINTERFACE_IMPL_3( CachedContentResultSetStubFactory,
579 				   XTypeProvider,
580 				   XServiceInfo,
581 				   XCachedContentResultSetStubFactory );
582 
583 //--------------------------------------------------------------------------
584 // CachedContentResultSetStubFactory XTypeProvider methods.
585 //--------------------------------------------------------------------------
586 
587 XTYPEPROVIDER_IMPL_3( CachedContentResultSetStubFactory,
588 					  XTypeProvider,
589 				   	  XServiceInfo,
590 					  XCachedContentResultSetStubFactory );
591 
592 //--------------------------------------------------------------------------
593 // CachedContentResultSetStubFactory XServiceInfo methods.
594 //--------------------------------------------------------------------------
595 
596 XSERVICEINFO_IMPL_1( CachedContentResultSetStubFactory,
597  		   		 OUString::createFromAscii(
598 				 	"com.sun.star.comp.ucb.CachedContentResultSetStubFactory" ),
599  		   		 OUString::createFromAscii(
600 				 	CACHED_CRS_STUB_FACTORY_NAME ) );
601 
602 //--------------------------------------------------------------------------
603 // Service factory implementation.
604 //--------------------------------------------------------------------------
605 
606 ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetStubFactory );
607 
608 //--------------------------------------------------------------------------
609 // CachedContentResultSetStubFactory XCachedContentResultSetStubFactory methods.
610 //--------------------------------------------------------------------------
611 
612 	//virtual
613 Reference< XResultSet > SAL_CALL CachedContentResultSetStubFactory
createCachedContentResultSetStub(const Reference<XResultSet> & xSource)614 	::createCachedContentResultSetStub(
615 			const Reference< XResultSet > & xSource )
616 			throw( RuntimeException )
617 {
618 	if( xSource.is() )
619 	{
620 		Reference< XResultSet > xRet;
621 		xRet = new CachedContentResultSetStub( xSource );
622 		return xRet;
623 	}
624 	return NULL;
625 }
626 
627 
628