Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <comphelper/processfactory.hxx>
21 : #include <ucbhelper/contentidentifier.hxx>
22 : #include <com/sun/star/ucb/OpenMode.hpp>
23 : #include <com/sun/star/uno/Reference.h>
24 : #include <com/sun/star/beans/PropertyAttribute.hpp>
25 : #include <com/sun/star/ucb/ListActionType.hpp>
26 : #include <com/sun/star/ucb/XSourceInitialization.hpp>
27 : #include <ucbhelper/resultsetmetadata.hxx>
28 :
29 : #include "resultsetbase.hxx"
30 :
31 : using namespace chelp;
32 : using namespace com::sun::star;
33 :
34 0 : ResultSetBase::ResultSetBase( const uno::Reference< uno::XComponentContext >& rxContext,
35 : const uno::Reference< ucb::XContentProvider >& xProvider,
36 : sal_Int32 nOpenMode,
37 : const uno::Sequence< beans::Property >& seq,
38 : const uno::Sequence< ucb::NumberedSortingInfo >& seqSort )
39 : : m_xContext( rxContext ),
40 : m_xProvider( xProvider ),
41 : m_nRow( -1 ),
42 : m_nWasNull( true ),
43 : m_nOpenMode( nOpenMode ),
44 : m_bRowCountFinal( true ),
45 : m_sProperty( seq ),
46 : m_sSortingInfo( seqSort ),
47 : m_pDisposeEventListeners( 0 ),
48 : m_pRowCountListeners( 0 ),
49 0 : m_pIsFinalListeners( 0 )
50 : {
51 0 : }
52 :
53 0 : ResultSetBase::~ResultSetBase()
54 : {
55 0 : delete m_pIsFinalListeners;
56 0 : delete m_pRowCountListeners;
57 0 : delete m_pDisposeEventListeners;
58 0 : }
59 :
60 :
61 : // XInterface
62 :
63 : void SAL_CALL
64 0 : ResultSetBase::acquire(
65 : void )
66 : throw()
67 : {
68 0 : OWeakObject::acquire();
69 0 : }
70 :
71 :
72 : void SAL_CALL
73 0 : ResultSetBase::release(
74 : void )
75 : throw()
76 : {
77 0 : OWeakObject::release();
78 0 : }
79 :
80 :
81 :
82 : uno::Any SAL_CALL
83 0 : ResultSetBase::queryInterface(
84 : const uno::Type& rType )
85 : throw( uno::RuntimeException, std::exception )
86 : {
87 : uno::Any aRet = cppu::queryInterface( rType,
88 : (static_cast< lang::XComponent* >(this)),
89 : (static_cast< sdbc::XRow* >(this)),
90 : (static_cast< sdbc::XResultSet* >(this)),
91 : (static_cast< sdbc::XResultSetMetaDataSupplier* >(this)),
92 : (static_cast< beans::XPropertySet* >(this)),
93 0 : (static_cast< ucb::XContentAccess* >(this)) );
94 0 : return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
95 : }
96 :
97 :
98 :
99 : // XComponent
100 :
101 :
102 : void SAL_CALL
103 0 : ResultSetBase::addEventListener(
104 : const uno::Reference< lang::XEventListener >& Listener )
105 : throw( uno::RuntimeException, std::exception )
106 : {
107 0 : osl::MutexGuard aGuard( m_aMutex );
108 :
109 0 : if ( ! m_pDisposeEventListeners )
110 : m_pDisposeEventListeners =
111 0 : new cppu::OInterfaceContainerHelper( m_aMutex );
112 :
113 0 : m_pDisposeEventListeners->addInterface( Listener );
114 0 : }
115 :
116 :
117 : void SAL_CALL
118 0 : ResultSetBase::removeEventListener(
119 : const uno::Reference< lang::XEventListener >& Listener )
120 : throw( uno::RuntimeException, std::exception )
121 : {
122 0 : osl::MutexGuard aGuard( m_aMutex );
123 :
124 0 : if ( m_pDisposeEventListeners )
125 0 : m_pDisposeEventListeners->removeInterface( Listener );
126 0 : }
127 :
128 :
129 :
130 : void SAL_CALL
131 0 : ResultSetBase::dispose()
132 : throw( uno::RuntimeException, std::exception )
133 : {
134 0 : osl::MutexGuard aGuard( m_aMutex );
135 :
136 0 : lang::EventObject aEvt;
137 0 : aEvt.Source = static_cast< lang::XComponent * >( this );
138 :
139 0 : if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
140 : {
141 0 : m_pDisposeEventListeners->disposeAndClear( aEvt );
142 : }
143 0 : if( m_pRowCountListeners && m_pRowCountListeners->getLength() )
144 : {
145 0 : m_pRowCountListeners->disposeAndClear( aEvt );
146 : }
147 0 : if( m_pIsFinalListeners && m_pIsFinalListeners->getLength() )
148 : {
149 0 : m_pIsFinalListeners->disposeAndClear( aEvt );
150 0 : }
151 0 : }
152 :
153 :
154 :
155 : // XResultSet
156 :
157 : sal_Bool SAL_CALL
158 0 : ResultSetBase::next(
159 : void )
160 : throw( sdbc::SQLException,
161 : uno::RuntimeException, std::exception )
162 : {
163 : sal_Bool test;
164 0 : m_nRow++;
165 0 : if( sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() )
166 0 : test = true;
167 : else
168 0 : test = false;
169 0 : return test;
170 : }
171 :
172 :
173 : sal_Bool SAL_CALL
174 0 : ResultSetBase::isBeforeFirst(
175 : void )
176 : throw( sdbc::SQLException,
177 : uno::RuntimeException, std::exception )
178 : {
179 0 : return m_nRow == -1;
180 : }
181 :
182 :
183 : sal_Bool SAL_CALL
184 0 : ResultSetBase::isAfterLast(
185 : void )
186 : throw( sdbc::SQLException,
187 : uno::RuntimeException, std::exception )
188 : {
189 0 : return sal::static_int_cast<sal_uInt32>( m_nRow ) >= m_aItems.size(); // Cannot happen, if m_aFolder.isOpen()
190 : }
191 :
192 :
193 : sal_Bool SAL_CALL
194 0 : ResultSetBase::isFirst(
195 : void )
196 : throw( sdbc::SQLException,
197 : uno::RuntimeException, std::exception )
198 : {
199 0 : return m_nRow == 0;
200 : }
201 :
202 :
203 : sal_Bool SAL_CALL
204 0 : ResultSetBase::isLast(
205 : void )
206 : throw( sdbc::SQLException,
207 : uno::RuntimeException, std::exception)
208 : {
209 0 : if( sal::static_int_cast<sal_uInt32>( m_nRow ) == m_aItems.size() - 1 )
210 0 : return true;
211 : else
212 0 : return false;
213 : }
214 :
215 :
216 : void SAL_CALL
217 0 : ResultSetBase::beforeFirst(
218 : void )
219 : throw( sdbc::SQLException,
220 : uno::RuntimeException, std::exception)
221 : {
222 0 : m_nRow = -1;
223 0 : }
224 :
225 :
226 : void SAL_CALL
227 0 : ResultSetBase::afterLast(
228 : void )
229 : throw( sdbc::SQLException,
230 : uno::RuntimeException, std::exception )
231 : {
232 0 : m_nRow = m_aItems.size();
233 0 : }
234 :
235 :
236 : sal_Bool SAL_CALL
237 0 : ResultSetBase::first(
238 : void )
239 : throw( sdbc::SQLException,
240 : uno::RuntimeException, std::exception)
241 : {
242 0 : m_nRow = -1;
243 0 : return next();
244 : }
245 :
246 :
247 : sal_Bool SAL_CALL
248 0 : ResultSetBase::last(
249 : void )
250 : throw( sdbc::SQLException,
251 : uno::RuntimeException, std::exception )
252 : {
253 0 : m_nRow = m_aItems.size() - 1;
254 0 : return true;
255 : }
256 :
257 :
258 : sal_Int32 SAL_CALL
259 0 : ResultSetBase::getRow(
260 : void )
261 : throw( sdbc::SQLException,
262 : uno::RuntimeException, std::exception)
263 : {
264 : // Test, whether behind last row
265 0 : if( -1 == m_nRow || sal::static_int_cast<sal_uInt32>( m_nRow ) >= m_aItems.size() )
266 0 : return 0;
267 : else
268 0 : return m_nRow+1;
269 : }
270 :
271 :
272 0 : sal_Bool SAL_CALL ResultSetBase::absolute( sal_Int32 row )
273 : throw( sdbc::SQLException, uno::RuntimeException, std::exception)
274 : {
275 0 : if( row >= 0 )
276 0 : m_nRow = row - 1;
277 : else
278 : {
279 0 : last();
280 0 : m_nRow += ( row + 1 );
281 0 : if( m_nRow < -1 )
282 0 : m_nRow = -1;
283 : }
284 :
285 0 : return 0<= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size();
286 : }
287 :
288 :
289 :
290 :
291 : sal_Bool SAL_CALL
292 0 : ResultSetBase::relative(
293 : sal_Int32 row )
294 : throw( sdbc::SQLException,
295 : uno::RuntimeException, std::exception)
296 : {
297 0 : if( isAfterLast() || isBeforeFirst() )
298 0 : throw sdbc::SQLException();
299 :
300 0 : if( row > 0 )
301 0 : while( row-- )
302 0 : next();
303 0 : else if( row < 0 )
304 0 : while( row++ && m_nRow > -1 )
305 0 : previous();
306 :
307 0 : return 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size();
308 : }
309 :
310 :
311 :
312 : sal_Bool SAL_CALL
313 0 : ResultSetBase::previous(
314 : void )
315 : throw( sdbc::SQLException,
316 : uno::RuntimeException, std::exception)
317 : {
318 0 : if( sal::static_int_cast<sal_uInt32>( m_nRow ) > m_aItems.size() )
319 0 : m_nRow = m_aItems.size(); // Correct Handling of afterLast
320 0 : if( 0 <= m_nRow ) -- m_nRow;
321 :
322 0 : return 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size();
323 : }
324 :
325 :
326 : void SAL_CALL
327 0 : ResultSetBase::refreshRow(
328 : void )
329 : throw( sdbc::SQLException,
330 : uno::RuntimeException, std::exception)
331 : {
332 0 : }
333 :
334 :
335 : sal_Bool SAL_CALL
336 0 : ResultSetBase::rowUpdated(
337 : void )
338 : throw( sdbc::SQLException,
339 : uno::RuntimeException, std::exception )
340 : {
341 0 : return false;
342 : }
343 :
344 : sal_Bool SAL_CALL
345 0 : ResultSetBase::rowInserted(
346 : void )
347 : throw( sdbc::SQLException,
348 : uno::RuntimeException, std::exception )
349 : {
350 0 : return false;
351 : }
352 :
353 : sal_Bool SAL_CALL
354 0 : ResultSetBase::rowDeleted(
355 : void )
356 : throw( sdbc::SQLException,
357 : uno::RuntimeException, std::exception )
358 : {
359 0 : return false;
360 : }
361 :
362 :
363 : uno::Reference< uno::XInterface > SAL_CALL
364 0 : ResultSetBase::getStatement(
365 : void )
366 : throw( sdbc::SQLException,
367 : uno::RuntimeException, std::exception )
368 : {
369 0 : uno::Reference< uno::XInterface > test( 0 );
370 0 : return test;
371 : }
372 :
373 :
374 : // XCloseable
375 :
376 : void SAL_CALL
377 0 : ResultSetBase::close(
378 : void )
379 : throw( sdbc::SQLException,
380 : uno::RuntimeException, std::exception)
381 : {
382 0 : }
383 :
384 :
385 : OUString SAL_CALL
386 0 : ResultSetBase::queryContentIdentifierString(
387 : void )
388 : throw( uno::RuntimeException, std::exception )
389 : {
390 0 : if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() )
391 0 : return m_aPath[m_nRow];
392 : else
393 0 : return OUString();
394 : }
395 :
396 :
397 : uno::Reference< ucb::XContentIdentifier > SAL_CALL
398 0 : ResultSetBase::queryContentIdentifier(
399 : void )
400 : throw( uno::RuntimeException, std::exception )
401 : {
402 0 : if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() )
403 : {
404 0 : OUString url = queryContentIdentifierString();
405 0 : if( ! m_aIdents[m_nRow].is() && !url.isEmpty() )
406 0 : m_aIdents[m_nRow] = uno::Reference< ucb::XContentIdentifier >(
407 0 : new ::ucbhelper::ContentIdentifier( url ) );
408 0 : return m_aIdents[m_nRow];
409 : }
410 :
411 0 : return uno::Reference< ucb::XContentIdentifier >();
412 : }
413 :
414 :
415 : uno::Reference< ucb::XContent > SAL_CALL
416 0 : ResultSetBase::queryContent(
417 : void )
418 : throw( uno::RuntimeException, std::exception )
419 : {
420 0 : if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() )
421 0 : return m_xProvider->queryContent( queryContentIdentifier() );
422 : else
423 0 : return uno::Reference< ucb::XContent >();
424 : }
425 :
426 :
427 :
428 0 : class XPropertySetInfoImpl
429 : : public cppu::OWeakObject,
430 : public beans::XPropertySetInfo
431 : {
432 : public:
433 :
434 0 : XPropertySetInfoImpl( const uno::Sequence< beans::Property >& aSeq )
435 0 : : m_aSeq( aSeq )
436 : {
437 0 : }
438 :
439 0 : void SAL_CALL acquire( void )
440 : throw() SAL_OVERRIDE
441 : {
442 0 : OWeakObject::acquire();
443 0 : }
444 :
445 :
446 0 : void SAL_CALL release( void )
447 : throw() SAL_OVERRIDE
448 : {
449 0 : OWeakObject::release();
450 0 : }
451 :
452 0 : uno::Any SAL_CALL queryInterface( const uno::Type& rType )
453 : throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE
454 : {
455 : uno::Any aRet = cppu::queryInterface( rType,
456 0 : (static_cast< beans::XPropertySetInfo* >(this)) );
457 0 : return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
458 : }
459 :
460 0 : uno::Sequence< beans::Property > SAL_CALL getProperties()
461 : throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE
462 : {
463 0 : return m_aSeq;
464 : }
465 :
466 0 : beans::Property SAL_CALL getPropertyByName( const OUString& aName )
467 : throw( beans::UnknownPropertyException,
468 : uno::RuntimeException, std::exception) SAL_OVERRIDE
469 : {
470 0 : for( int i = 0; i < m_aSeq.getLength(); ++i )
471 0 : if( aName == m_aSeq[i].Name )
472 0 : return m_aSeq[i];
473 0 : throw beans::UnknownPropertyException();
474 : }
475 :
476 0 : sal_Bool SAL_CALL hasPropertyByName( const OUString& Name )
477 : throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE
478 : {
479 0 : for( int i = 0; i < m_aSeq.getLength(); ++i )
480 0 : if( Name == m_aSeq[i].Name )
481 0 : return true;
482 0 : return false;
483 : }
484 :
485 : private:
486 :
487 : uno::Sequence< beans::Property > m_aSeq;
488 : };
489 :
490 :
491 :
492 : // XPropertySet
493 : uno::Reference< beans::XPropertySetInfo > SAL_CALL
494 0 : ResultSetBase::getPropertySetInfo()
495 : throw( uno::RuntimeException, std::exception)
496 : {
497 0 : uno::Sequence< beans::Property > seq(2);
498 0 : seq[0].Name = "RowCount";
499 0 : seq[0].Handle = -1;
500 0 : seq[0].Type = getCppuType( static_cast< sal_Int32* >(0) );
501 0 : seq[0].Attributes = beans::PropertyAttribute::READONLY;
502 :
503 0 : seq[1].Name = "IsRowCountFinal";
504 0 : seq[1].Handle = -1;
505 0 : seq[1].Type = getCppuType( static_cast< sal_Bool* >(0) );
506 0 : seq[1].Attributes = beans::PropertyAttribute::READONLY;
507 :
508 : //t
509 0 : return uno::Reference< beans::XPropertySetInfo > ( new XPropertySetInfoImpl( seq ) );
510 : }
511 :
512 :
513 :
514 0 : void SAL_CALL ResultSetBase::setPropertyValue(
515 : const OUString& aPropertyName, const uno::Any& aValue )
516 : throw( beans::UnknownPropertyException,
517 : beans::PropertyVetoException,
518 : lang::IllegalArgumentException,
519 : lang::WrappedTargetException,
520 : uno::RuntimeException, std::exception)
521 : {
522 : (void)aValue;
523 :
524 0 : if( aPropertyName == "IsRowCountFinal" ||
525 0 : aPropertyName == "RowCount" )
526 0 : return;
527 :
528 0 : throw beans::UnknownPropertyException();
529 : }
530 :
531 :
532 0 : uno::Any SAL_CALL ResultSetBase::getPropertyValue(
533 : const OUString& PropertyName )
534 : throw( beans::UnknownPropertyException,
535 : lang::WrappedTargetException,
536 : uno::RuntimeException, std::exception)
537 : {
538 0 : if( PropertyName == "IsRowCountFinal" )
539 : {
540 0 : uno::Any aAny;
541 0 : aAny <<= m_bRowCountFinal;
542 0 : return aAny;
543 : }
544 0 : else if ( PropertyName == "RowCount" )
545 : {
546 0 : uno::Any aAny;
547 0 : sal_Int32 count = m_aItems.size();
548 0 : aAny <<= count;
549 0 : return aAny;
550 : }
551 : else
552 0 : throw beans::UnknownPropertyException();
553 : }
554 :
555 :
556 0 : void SAL_CALL ResultSetBase::addPropertyChangeListener(
557 : const OUString& aPropertyName,
558 : const uno::Reference< beans::XPropertyChangeListener >& xListener )
559 : throw( beans::UnknownPropertyException,
560 : lang::WrappedTargetException,
561 : uno::RuntimeException, std::exception)
562 : {
563 0 : if( aPropertyName == "IsRowCountFinal" )
564 : {
565 0 : osl::MutexGuard aGuard( m_aMutex );
566 0 : if ( ! m_pIsFinalListeners )
567 : m_pIsFinalListeners =
568 0 : new cppu::OInterfaceContainerHelper( m_aMutex );
569 :
570 0 : m_pIsFinalListeners->addInterface( xListener );
571 : }
572 0 : else if ( aPropertyName == "RowCount" )
573 : {
574 0 : osl::MutexGuard aGuard( m_aMutex );
575 0 : if ( ! m_pRowCountListeners )
576 : m_pRowCountListeners =
577 0 : new cppu::OInterfaceContainerHelper( m_aMutex );
578 0 : m_pRowCountListeners->addInterface( xListener );
579 : }
580 : else
581 0 : throw beans::UnknownPropertyException();
582 0 : }
583 :
584 :
585 0 : void SAL_CALL ResultSetBase::removePropertyChangeListener(
586 : const OUString& aPropertyName,
587 : const uno::Reference< beans::XPropertyChangeListener >& aListener )
588 : throw( beans::UnknownPropertyException,
589 : lang::WrappedTargetException,
590 : uno::RuntimeException, std::exception)
591 : {
592 0 : if( aPropertyName == "IsRowCountFinal" &&
593 : m_pIsFinalListeners )
594 : {
595 0 : osl::MutexGuard aGuard( m_aMutex );
596 0 : m_pIsFinalListeners->removeInterface( aListener );
597 : }
598 0 : else if ( aPropertyName == "RowCount" &&
599 : m_pRowCountListeners )
600 : {
601 0 : osl::MutexGuard aGuard( m_aMutex );
602 0 : m_pRowCountListeners->removeInterface( aListener );
603 : }
604 : else
605 0 : throw beans::UnknownPropertyException();
606 0 : }
607 :
608 :
609 0 : void SAL_CALL ResultSetBase::addVetoableChangeListener(
610 : const OUString& PropertyName,
611 : const uno::Reference< beans::XVetoableChangeListener >& aListener )
612 : throw( beans::UnknownPropertyException,
613 : lang::WrappedTargetException,
614 : uno::RuntimeException, std::exception)
615 : {
616 : (void)PropertyName;
617 : (void)aListener;
618 0 : }
619 :
620 :
621 0 : void SAL_CALL ResultSetBase::removeVetoableChangeListener(
622 : const OUString& PropertyName,
623 : const uno::Reference< beans::XVetoableChangeListener >& aListener )
624 : throw( beans::UnknownPropertyException,
625 : lang::WrappedTargetException,
626 : uno::RuntimeException, std::exception)
627 : {
628 : (void)PropertyName;
629 : (void)aListener;
630 0 : }
631 :
632 :
633 :
634 : // XResultSetMetaDataSupplier
635 : uno::Reference< sdbc::XResultSetMetaData > SAL_CALL
636 0 : ResultSetBase::getMetaData(
637 : void )
638 : throw( sdbc::SQLException,
639 : uno::RuntimeException, std::exception )
640 : {
641 : ::ucbhelper::ResultSetMetaData* p =
642 0 : new ::ucbhelper::ResultSetMetaData( m_xContext, m_sProperty );
643 0 : return uno::Reference< sdbc::XResultSetMetaData >( p );
644 : }
645 :
646 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|