bump product version to 6.3.0.0.beta1
[LibreOffice.git] / connectivity / source / drivers / postgresql / pq_xcontainer.cxx
blob2082816813fdb61dcf0c2e397d9d12bf114e5f16
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * Effective License of whole file:
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License version 2.1, as published by the Free Software Foundation.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
20 * Parts "Copyright by Sun Microsystems, Inc" prior to August 2011:
22 * The Contents of this file are made available subject to the terms of
23 * the GNU Lesser General Public License Version 2.1
25 * Copyright: 2000 by Sun Microsystems, Inc.
27 * Contributor(s): Joerg Budischewski
29 * All parts contributed on or after August 2011:
31 * This Source Code Form is subject to the terms of the Mozilla Public
32 * License, v. 2.0. If a copy of the MPL was not distributed with this
33 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
35 ************************************************************************/
37 #include <rtl/ustrbuf.hxx>
38 #include <com/sun/star/container/ElementExistException.hpp>
39 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
40 #include <cppuhelper/implbase.hxx>
42 #include "pq_xcontainer.hxx"
43 #include "pq_statics.hxx"
44 #include "pq_tools.hxx"
46 using osl::MutexGuard;
48 using com::sun::star::beans::XPropertySet;
50 using com::sun::star::uno::Any;
51 using com::sun::star::uno::makeAny;
52 using com::sun::star::uno::Type;
53 using com::sun::star::uno::XInterface;
54 using com::sun::star::uno::Reference;
55 using com::sun::star::uno::Sequence;
56 using com::sun::star::uno::RuntimeException;
58 using com::sun::star::container::NoSuchElementException;
59 using com::sun::star::container::XEnumeration;
60 using com::sun::star::container::XContainerListener;
61 using com::sun::star::container::ContainerEvent;
62 using com::sun::star::lang::IndexOutOfBoundsException;
63 using com::sun::star::lang::XEventListener;
66 namespace pq_sdbc_driver
69 class ReplacedBroadcaster : public EventBroadcastHelper
71 ContainerEvent m_event;
72 public:
73 ReplacedBroadcaster(
74 const Reference< XInterface > & source,
75 const OUString & name,
76 const Any & newElement,
77 const OUString & oldElement ) :
78 m_event( source, makeAny( name ), newElement, makeAny(oldElement) )
81 virtual void fire( XEventListener * listener ) const override
83 static_cast<XContainerListener*>(listener)->elementReplaced( m_event );
85 virtual Type getType() const override
87 return cppu::UnoType<XContainerListener>::get();
91 class InsertedBroadcaster : public EventBroadcastHelper
93 public:
94 ContainerEvent m_event;
95 InsertedBroadcaster(
96 const Reference< XInterface > & source,
97 const OUString & name,
98 const Any & newElement ) :
99 m_event( source, makeAny( name ), newElement, Any() )
102 virtual void fire( XEventListener * listener ) const override
104 static_cast<XContainerListener*>(listener)->elementInserted( m_event );
107 virtual Type getType() const override
109 return cppu::UnoType<XContainerListener>::get();
113 class RemovedBroadcaster : public EventBroadcastHelper
115 public:
116 ContainerEvent m_event;
117 RemovedBroadcaster(
118 const Reference< XInterface > & source,
119 const OUString & name) :
120 m_event( source, makeAny( name ), Any(), Any() )
123 virtual void fire( XEventListener * listener ) const override
125 static_cast<XContainerListener*>(listener)->elementRemoved( m_event );
128 virtual Type getType() const override
130 return cppu::UnoType<XContainerListener>::get();
134 Container::Container(
135 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
136 const css::uno::Reference< css::sdbc::XConnection > & origin,
137 ConnectionSettings *pSettings,
138 const OUString &type)
139 : ContainerBase( refMutex->GetMutex() ),
140 m_xMutex( refMutex ),
141 m_pSettings( pSettings ),
142 m_origin( origin ),
143 m_type( type )
147 Any Container::getByName( const OUString& aName )
149 String2IntMap::const_iterator ii = m_name2index.find( aName );
150 if( ii == m_name2index.end() )
152 throw NoSuchElementException(
153 "Element " + aName + " unknown in " + m_type + "-Container",
154 *this );
156 OSL_ASSERT( ii->second >= 0 && ii->second < static_cast<int>(m_values.size()) );
157 return m_values[ ii->second ];
160 Sequence< OUString > Container::getElementNames( )
162 Sequence< OUString > ret( m_values.size() );
163 for( const auto& [rName, rIndex] : m_name2index )
165 // give element names in index order !
166 ret[rIndex] = rName;
168 return ret;
171 sal_Bool Container::hasByName( const OUString& aName )
173 return m_name2index.find( aName ) != m_name2index.end();
175 // Methods
176 Type Container::getElementType( )
178 return Type();
181 sal_Bool Container::hasElements( )
183 return ! m_name2index.empty();
186 Any Container::getByIndex( sal_Int32 Index )
188 if( Index < 0 || Index >= static_cast<sal_Int32>(m_values.size()) )
190 throw IndexOutOfBoundsException(
191 "Index " + OUString::number( Index )
192 + " out of range for " + m_type + "-Container, expected 0 <= x <= "
193 + OUString::number(m_values.size() -1),
194 *this );
196 return m_values[Index];
199 sal_Int32 Container::getCount()
201 return m_values.size();
205 class ContainerEnumeration : public ::cppu::WeakImplHelper< XEnumeration >
207 std::vector< css::uno::Any > m_vec;
208 sal_Int32 m_index;
209 public:
210 explicit ContainerEnumeration( const std::vector< css::uno::Any > &vec )
211 : m_vec( vec ),
212 m_index( -1 )
215 public:
216 // XEnumeration
217 virtual sal_Bool SAL_CALL hasMoreElements( ) override;
218 virtual css::uno::Any SAL_CALL nextElement( ) override;
222 sal_Bool ContainerEnumeration::hasMoreElements()
224 return static_cast<int>(m_vec.size()) > m_index +1;
227 css::uno::Any ContainerEnumeration::nextElement()
229 if( ! hasMoreElements() )
231 throw NoSuchElementException(
232 "NoSuchElementException during enumeration", *this );
234 m_index ++;
235 return m_vec[m_index];
238 Reference< XEnumeration > Container::createEnumeration( )
240 return new ContainerEnumeration( m_values );
243 void Container::addRefreshListener(
244 const css::uno::Reference< css::util::XRefreshListener >& l )
246 rBHelper.addListener( cppu::UnoType<decltype(l)>::get() , l );
249 void Container::removeRefreshListener(
250 const css::uno::Reference< css::util::XRefreshListener >& l )
252 rBHelper.removeListener( cppu::UnoType<decltype(l)>::get() , l );
255 void Container::disposing()
257 m_origin.clear();
260 void Container::rename( const OUString &oldName, const OUString &newName )
262 Any newValue;
264 osl::MutexGuard guard ( m_xMutex->GetMutex() );
265 String2IntMap::iterator ii = m_name2index.find( oldName );
266 if( ii != m_name2index.end() )
268 sal_Int32 nIndex = ii->second;
269 newValue = m_values[nIndex];
270 m_name2index.erase( ii );
271 m_name2index[ newName ] = nIndex;
274 fire( ReplacedBroadcaster( *this, newName, newValue, oldName ) );
275 fire( RefreshedBroadcaster( *this ) );
278 void Container::dropByName( const OUString& elementName )
280 osl::MutexGuard guard( m_xMutex->GetMutex() );
281 String2IntMap::const_iterator ii = m_name2index.find( elementName );
282 if( ii == m_name2index.end() )
284 throw css::container::NoSuchElementException(
285 "Column " + elementName + " is unknown in "
286 + m_type + " container, so it can't be dropped",
287 *this );
289 dropByIndex( ii->second );
292 void Container::dropByIndex( sal_Int32 index )
294 osl::MutexGuard guard( m_xMutex->GetMutex() );
295 if( index < 0 || index >=static_cast<sal_Int32>(m_values.size()) )
297 throw css::lang::IndexOutOfBoundsException(
298 "Index out of range (allowed 0 to "
299 + OUString::number(m_values.size() -1)
300 + ", got " + OUString::number( index )
301 + ") in " + m_type,
302 *this );
305 OUString name;
306 String2IntMap::iterator ii = std::find_if(m_name2index.begin(), m_name2index.end(),
307 [&index](const String2IntMap::value_type& rEntry) { return rEntry.second == index; });
308 if (ii != m_name2index.end())
310 name = ii->first;
311 m_name2index.erase( ii );
314 for( int i = index +1 ; i < static_cast<int>(m_values.size()) ; i ++ )
316 m_values[i-1] = m_values[i];
318 // I know, this is expensive, but don't want to maintain another map ...
319 ii = std::find_if(m_name2index.begin(), m_name2index.end(),
320 [&i](const String2IntMap::value_type& rEntry) { return rEntry.second == i; });
321 if (ii != m_name2index.end())
323 ii->second = i-1;
326 m_values.resize( m_values.size() - 1 );
328 fire( RemovedBroadcaster( *this, name ) );
331 void Container::append(
332 const OUString & name,
333 const css::uno::Reference< css::beans::XPropertySet >& descriptor )
336 osl::MutexGuard guard( m_xMutex->GetMutex() );
338 if( hasByName( name ) )
340 throw css::container::ElementExistException(
341 "a " + m_type + " with name " + name + " already exists in this container",
342 *this );
345 int index = m_values.size();
346 m_values.push_back( makeAny( descriptor ) );
347 m_name2index[name] = index;
349 fire( InsertedBroadcaster( *this, name, makeAny( descriptor ) ) );
352 void Container::appendByDescriptor(
353 const css::uno::Reference< css::beans::XPropertySet >& descriptor)
355 append( extractStringProperty( descriptor, getStatics().NAME ), descriptor );
359 void Container::addContainerListener(
360 const css::uno::Reference< css::container::XContainerListener >& l )
362 rBHelper.addListener( cppu::UnoType<decltype(l)>::get() , l );
365 void Container::removeContainerListener(
366 const css::uno::Reference< css::container::XContainerListener >& l )
368 rBHelper.removeListener( cppu::UnoType<decltype(l)>::get() , l );
372 void Container::fire( const EventBroadcastHelper &helper )
374 cppu::OInterfaceContainerHelper *container = rBHelper.getContainer( helper.getType() );
375 if( container )
377 cppu::OInterfaceIteratorHelper iterator( * container );
378 while( iterator.hasMoreElements() )
382 helper.fire( static_cast<XEventListener *>(iterator.next()) );
384 catch ( css::uno::RuntimeException & )
386 OSL_ENSURE( false, "exception caught" );
387 // loose coupling, a runtime exception shall not break anything
388 // TODO: log away as warning !
390 catch( css::uno::Exception & )
392 OSL_ENSURE( false, "exception from listener flying through" );
393 throw;
402 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */