Update ooo320-m1
[ooovba.git] / connectivity / source / drivers / postgresql / pq_xcontainer.cxx
blob9bf8908fa08e480f6c845aaedddf0f509b7f92bf
1 /*************************************************************************
3 * $RCSfile: pq_xcontainer.cxx,v $
5 * $Revision: 1.1.2.5 $
7 * last change: $Author: jbu $ $Date: 2007/01/07 13:50:38 $
9 * The Contents of this file are made available subject to the terms of
10 * either of the following licenses
12 * - GNU Lesser General Public License Version 2.1
13 * - Sun Industry Standards Source License Version 1.1
15 * Sun Microsystems Inc., October, 2000
17 * GNU Lesser General Public License Version 2.1
18 * =============================================
19 * Copyright 2000 by Sun Microsystems, Inc.
20 * 901 San Antonio Road, Palo Alto, CA 94303, USA
22 * This library is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License version 2.1, as published by the Free Software Foundation.
26 * This library is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * Lesser General Public License for more details.
31 * You should have received a copy of the GNU Lesser General Public
32 * License along with this library; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
34 * MA 02111-1307 USA
37 * Sun Industry Standards Source License Version 1.1
38 * =================================================
39 * The contents of this file are subject to the Sun Industry Standards
40 * Source License Version 1.1 (the "License"); You may not use this file
41 * except in compliance with the License. You may obtain a copy of the
42 * License at http://www.openoffice.org/license.html.
44 * Software provided under this License is provided on an "AS IS" basis,
45 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
46 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
47 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
48 * See the License for the specific provisions governing your rights and
49 * obligations concerning the Software.
51 * The Initial Developer of the Original Code is: Joerg Budischewski
53 * Copyright: 2000 by Sun Microsystems, Inc.
55 * All Rights Reserved.
57 * Contributor(s): Joerg Budischewski
60 ************************************************************************/
62 #include <rtl/ustrbuf.hxx>
64 #include <com/sun/star/sdbc/XRow.hpp>
65 #include <com/sun/star/sdbc/XParameters.hpp>
68 #include <cppuhelper/implbase1.hxx>
70 #include "pq_xcontainer.hxx"
71 #include "pq_statics.hxx"
72 #include "pq_tools.hxx"
74 using osl::MutexGuard;
76 using rtl::OUString;
77 using rtl::OUStringBuffer;
78 using rtl::OUStringToOString;
80 using com::sun::star::beans::XPropertySet;
82 using com::sun::star::uno::Any;
83 using com::sun::star::uno::makeAny;
84 using com::sun::star::uno::UNO_QUERY;
85 using com::sun::star::uno::Type;
86 using com::sun::star::uno::XInterface;
87 using com::sun::star::uno::Reference;
88 using com::sun::star::uno::Sequence;
89 using com::sun::star::uno::RuntimeException;
91 using com::sun::star::container::NoSuchElementException;
92 using com::sun::star::container::XEnumeration;
93 using com::sun::star::container::XContainerListener;
94 using com::sun::star::container::ContainerEvent;
95 using com::sun::star::lang::IndexOutOfBoundsException;
96 using com::sun::star::lang::XEventListener;
98 using com::sun::star::lang::WrappedTargetException;
100 using com::sun::star::sdbc::XRow;
101 using com::sun::star::sdbc::XCloseable;
102 using com::sun::star::sdbc::XStatement;
103 using com::sun::star::sdbc::XResultSet;
104 using com::sun::star::sdbc::XParameters;
105 using com::sun::star::sdbc::XPreparedStatement;
106 using com::sun::star::sdbcx::XDataDescriptorFactory;
108 namespace pq_sdbc_driver
110 #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
113 class ReplacedBroadcaster : public EventBroadcastHelper
115 ContainerEvent m_event;
116 public:
117 ReplacedBroadcaster(
118 const Reference< XInterface > & source,
119 const rtl::OUString & name,
120 const Any & newElement,
121 const rtl::OUString & oldElement ) :
122 m_event( source, makeAny( name ), newElement, makeAny(oldElement) )
125 virtual void fire( XEventListener * listener ) const
127 ((XContainerListener*)listener)->elementReplaced( m_event );
129 virtual Type getType() const
131 return getCppuType( (Reference< XContainerListener > *)0 );
135 class InsertedBroadcaster : public EventBroadcastHelper
137 public:
138 ContainerEvent m_event;
139 InsertedBroadcaster(
140 const Reference< XInterface > & source,
141 const rtl::OUString & name,
142 const Any & newElement ) :
143 m_event( source, makeAny( name ), newElement, Any() )
146 virtual void fire( XEventListener * listener ) const
148 ((XContainerListener*)listener)->elementInserted( m_event );
151 virtual Type getType() const
153 return getCppuType( (Reference< XContainerListener > *)0 );
157 class RemovedBroadcaster : public EventBroadcastHelper
159 public:
160 ContainerEvent m_event;
161 RemovedBroadcaster(
162 const Reference< XInterface > & source,
163 const rtl::OUString & name) :
164 m_event( source, makeAny( name ), Any(), Any() )
167 virtual void fire( XEventListener * listener ) const
169 ((XContainerListener*)listener)->elementRemoved( m_event );
172 virtual Type getType() const
174 return getCppuType( (Reference< XContainerListener > *)0 );
178 Container::Container(
179 const ::rtl::Reference< RefCountedMutex > & refMutex,
180 const ::com::sun::star::uno::Reference< com::sun::star::sdbc::XConnection > & origin,
181 ConnectionSettings *pSettings,
182 const ::rtl::OUString &type)
183 : ContainerBase( refMutex->mutex ),
184 m_refMutex( refMutex ),
185 m_pSettings( pSettings ),
186 m_origin( origin ),
187 m_type( type )
191 Any Container::getByName( const ::rtl::OUString& aName )
192 throw (NoSuchElementException,WrappedTargetException,RuntimeException)
194 String2IntMap::const_iterator ii = m_name2index.find( aName );
195 if( ii == m_name2index.end() )
197 OUStringBuffer buf(128);
198 buf.appendAscii( "Element " );
199 buf.append( aName );
200 buf.appendAscii( " unknown in " );
201 buf.append( m_type );
202 buf.appendAscii( "-Container" );
203 throw NoSuchElementException( buf.makeStringAndClear() , *this );
205 OSL_ASSERT( ii->second >= 0 && ii->second < m_values.getLength() );
206 return m_values[ ii->second ];
209 Sequence< OUString > Container::getElementNames( )
210 throw (::com::sun::star::uno::RuntimeException)
212 Sequence< OUString > ret( m_values.getLength() );
213 for( String2IntMap::const_iterator ii = m_name2index.begin();
214 ii != m_name2index.end() ;
215 ++ ii )
217 // give element names in index order !
218 ret[ii->second] = ii->first;
219 // ret[i] = ii->first;
221 return ret;
224 sal_Bool Container::hasByName( const ::rtl::OUString& aName )
225 throw (::com::sun::star::uno::RuntimeException)
227 return m_name2index.find( aName ) != m_name2index.end();
229 // Methods
230 Type Container::getElementType( )
231 throw (::com::sun::star::uno::RuntimeException)
233 return Type();
236 sal_Bool Container::hasElements( )
237 throw (::com::sun::star::uno::RuntimeException)
239 return ! m_name2index.empty();
242 Any Container::getByIndex( sal_Int32 Index )
243 throw (::com::sun::star::lang::IndexOutOfBoundsException,
244 ::com::sun::star::lang::WrappedTargetException,
245 ::com::sun::star::uno::RuntimeException)
247 if( Index < 0 || Index >= m_values.getLength() )
249 OUStringBuffer buf(128);
250 buf.appendAscii( "Index " );
251 buf.append( Index );
252 buf.appendAscii(" out of range for " );
253 buf.append( m_type );
254 buf.appendAscii("-Container, expected 0 <= x <= " );
255 buf.append( (sal_Int32 ) (m_values.getLength() -1));
256 throw IndexOutOfBoundsException( buf.makeStringAndClear(), *this );
258 return m_values[Index];
261 sal_Int32 Container::getCount()
262 throw (::com::sun::star::uno::RuntimeException)
264 return m_values.getLength();
268 class ContainerEnumeration : public ::cppu::WeakImplHelper1< XEnumeration >
270 com::sun::star::uno::Sequence< com::sun::star::uno::Any > m_vec;
271 sal_Int32 m_index;
272 public:
273 ContainerEnumeration( const com::sun::star::uno::Sequence< com::sun::star::uno::Any > &vec )
274 : m_vec( vec ),
275 m_index( -1 )
278 public:
279 // XEnumeration
280 virtual sal_Bool SAL_CALL hasMoreElements( )
281 throw (::com::sun::star::uno::RuntimeException);
282 virtual ::com::sun::star::uno::Any SAL_CALL nextElement( )
283 throw (::com::sun::star::container::NoSuchElementException,
284 ::com::sun::star::lang::WrappedTargetException,
285 ::com::sun::star::uno::RuntimeException);
289 sal_Bool ContainerEnumeration::hasMoreElements()
290 throw (::com::sun::star::uno::RuntimeException)
292 return m_vec.getLength() > m_index +1;
295 com::sun::star::uno::Any ContainerEnumeration::nextElement()
296 throw (::com::sun::star::container::NoSuchElementException,
297 ::com::sun::star::lang::WrappedTargetException,
298 ::com::sun::star::uno::RuntimeException)
300 if( ! hasMoreElements() )
302 throw NoSuchElementException(
303 ASCII_STR( "NoSuchElementException during enumeration" ), *this );
305 m_index ++;
306 return m_vec[m_index];
309 Reference< XEnumeration > Container::createEnumeration( )
310 throw (::com::sun::star::uno::RuntimeException)
312 return new ContainerEnumeration( m_values );
315 void Container::addRefreshListener(
316 const ::com::sun::star::uno::Reference< ::com::sun::star::util::XRefreshListener >& l )
317 throw (::com::sun::star::uno::RuntimeException)
319 rBHelper.addListener( getCppuType(&l) , l );
322 void Container::removeRefreshListener(
323 const ::com::sun::star::uno::Reference< ::com::sun::star::util::XRefreshListener >& l )
324 throw (::com::sun::star::uno::RuntimeException)
326 rBHelper.removeListener( getCppuType(&l) , l );
329 void Container::disposing()
331 m_origin.clear();
334 void Container::rename( const rtl::OUString &oldName, const rtl::OUString &newName )
336 Any newValue;
338 osl::MutexGuard guard ( m_refMutex->mutex );
339 String2IntMap::iterator ii = m_name2index.find( oldName );
340 if( ii != m_name2index.end() )
342 sal_Int32 nIndex = ii->second;
343 newValue = m_values[nIndex];
344 m_name2index.erase( ii );
345 m_name2index[ newName ] = nIndex;
346 newValue = m_values[nIndex];
349 fire( ReplacedBroadcaster( *this, newName, newValue, oldName ) );
350 fire( RefreshedBroadcaster( *this ) );
353 void Container::dropByName( const ::rtl::OUString& elementName )
354 throw (::com::sun::star::sdbc::SQLException,
355 ::com::sun::star::container::NoSuchElementException,
356 ::com::sun::star::uno::RuntimeException)
358 osl::MutexGuard guard( m_refMutex->mutex );
359 String2IntMap::const_iterator ii = m_name2index.find( elementName );
360 if( ii == m_name2index.end() )
362 OUStringBuffer buf( 128 );
363 buf.appendAscii( "Column " );
364 buf.append( elementName );
365 buf.appendAscii( " is unknown in " );
366 buf.append( m_type );
367 // buf.appendAscii( " " );
368 // buf.append( m_schemaName );
369 // buf.appendAscii( "." );
370 // buf.append( m_tableName );
371 buf.appendAscii( " container, so it can't be dropped" );
372 throw com::sun::star::container::NoSuchElementException(
373 buf.makeStringAndClear(), *this );
375 dropByIndex( ii->second );
378 void Container::dropByIndex( sal_Int32 index )
379 throw (::com::sun::star::sdbc::SQLException,
380 ::com::sun::star::lang::IndexOutOfBoundsException,
381 ::com::sun::star::uno::RuntimeException)
383 osl::MutexGuard guard( m_refMutex->mutex );
384 if( index < 0 || index >= m_values.getLength() )
386 OUStringBuffer buf( 128 );
387 buf.appendAscii( "Index out of range (allowed 0 to " );
388 buf.append((sal_Int32)(m_values.getLength() -1) );
389 buf.appendAscii( ", got " );
390 buf.append( index );
391 buf.appendAscii( ") in " );
392 buf.append( m_type );
393 throw com::sun::star::lang::IndexOutOfBoundsException(
394 buf.makeStringAndClear(), *this );
397 OUString name;
398 for( String2IntMap::iterator ii = m_name2index.begin() ;
399 ii != m_name2index.end() ;
400 ++ ii )
402 if( ii->second == index )
404 name = ii->first;
405 m_name2index.erase( ii );
406 break;
410 Any oldElement = m_values[index];
411 for( int i = index +1 ; i < m_values.getLength() ; i ++ )
413 m_values[i-1] = m_values[i];
415 // I know, this is expensive, but don't want to maintain another map ...
416 for( String2IntMap::iterator ii = m_name2index.begin() ;
417 ii != m_name2index.end() ;
418 ++ ii )
420 if( ii->second == i )
422 ii->second = i-1;
423 break;
427 m_values.realloc( m_values.getLength() - 1 );
429 fire( RemovedBroadcaster( *this, name ) );
432 void Container::append(
433 const rtl::OUString & name,
434 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor )
435 throw ( ::com::sun::star::container::ElementExistException )
438 osl::MutexGuard guard( m_refMutex->mutex );
440 if( hasByName( name ) )
442 OUStringBuffer buf( 128 );
443 buf.appendAscii( "a ");
444 buf.append( m_type );
445 buf.appendAscii( " with name " );
446 buf.append( name );
447 buf.appendAscii( " already exists in this container" );
448 throw com::sun::star::container::ElementExistException(
449 buf.makeStringAndClear() , *this );
452 int index = m_values.getLength();
453 m_values.realloc( m_values.getLength() + 1 );
454 m_values[index] = makeAny( descriptor );
455 m_name2index[name] = index;
457 fire( InsertedBroadcaster( *this, name, makeAny( descriptor ) ) );
460 void Container::appendByDescriptor(
461 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& descriptor)
462 throw (::com::sun::star::sdbc::SQLException,
463 ::com::sun::star::container::ElementExistException,
464 ::com::sun::star::uno::RuntimeException)
466 append( extractStringProperty( descriptor, getStatics().NAME ), descriptor );
470 void Container::addContainerListener(
471 const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& l )
472 throw (::com::sun::star::uno::RuntimeException)
474 rBHelper.addListener( getCppuType(&l) , l );
477 void Container::removeContainerListener(
478 const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& l )
479 throw (::com::sun::star::uno::RuntimeException)
481 rBHelper.removeListener( getCppuType(&l) , l );
485 void Container::fire( const EventBroadcastHelper &helper )
487 Reference< ::com::sun::star::util::XRefreshListener > l;
488 cppu::OInterfaceContainerHelper *container = rBHelper.getContainer( helper.getType() );
489 if( container )
491 cppu::OInterfaceIteratorHelper iterator( * container );
492 while( iterator.hasMoreElements() )
496 helper.fire( (XEventListener * ) iterator.next() );
498 catch ( com::sun::star::uno::RuntimeException & e )
500 OSL_ENSURE( 0, "exception catched" );
501 // loose coupling, a runtime exception shall not break anything
502 // TODO: log away as warning !
504 catch( com::sun::star::uno::Exception & e )
506 OSL_ENSURE( 0, "exception from listener flying through" );
507 throw;