nss: upgrade to release 3.73
[LibreOffice.git] / connectivity / source / drivers / postgresql / pq_xcontainer.cxx
blob06323615f4b7105e37a2523e8f082017f8857415
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 <com/sun/star/container/ElementExistException.hpp>
38 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
39 #include <cppuhelper/implbase.hxx>
41 #include "pq_xcontainer.hxx"
42 #include "pq_statics.hxx"
43 #include "pq_tools.hxx"
45 using osl::MutexGuard;
47 using com::sun::star::beans::XPropertySet;
49 using com::sun::star::uno::Any;
50 using com::sun::star::uno::makeAny;
51 using com::sun::star::uno::Type;
52 using com::sun::star::uno::XInterface;
53 using com::sun::star::uno::Reference;
54 using com::sun::star::uno::Sequence;
55 using com::sun::star::uno::RuntimeException;
57 using com::sun::star::container::NoSuchElementException;
58 using com::sun::star::container::XEnumeration;
59 using com::sun::star::container::XContainerListener;
60 using com::sun::star::container::ContainerEvent;
61 using com::sun::star::lang::IndexOutOfBoundsException;
62 using com::sun::star::lang::XEventListener;
65 namespace pq_sdbc_driver
68 namespace {
70 class ReplacedBroadcaster : public EventBroadcastHelper
72 ContainerEvent m_event;
73 public:
74 ReplacedBroadcaster(
75 const Reference< XInterface > & source,
76 const OUString & name,
77 const Any & newElement,
78 const OUString & oldElement ) :
79 m_event( source, makeAny( name ), newElement, makeAny(oldElement) )
82 virtual void fire( XEventListener * listener ) const override
84 static_cast<XContainerListener*>(listener)->elementReplaced( m_event );
86 virtual Type getType() const override
88 return cppu::UnoType<XContainerListener>::get();
92 class InsertedBroadcaster : public EventBroadcastHelper
94 public:
95 ContainerEvent m_event;
96 InsertedBroadcaster(
97 const Reference< XInterface > & source,
98 const OUString & name,
99 const Any & newElement ) :
100 m_event( source, makeAny( name ), newElement, Any() )
103 virtual void fire( XEventListener * listener ) const override
105 static_cast<XContainerListener*>(listener)->elementInserted( m_event );
108 virtual Type getType() const override
110 return cppu::UnoType<XContainerListener>::get();
114 class RemovedBroadcaster : public EventBroadcastHelper
116 public:
117 ContainerEvent m_event;
118 RemovedBroadcaster(
119 const Reference< XInterface > & source,
120 const OUString & name) :
121 m_event( source, makeAny( name ), Any(), Any() )
124 virtual void fire( XEventListener * listener ) const override
126 static_cast<XContainerListener*>(listener)->elementRemoved( m_event );
129 virtual Type getType() const override
131 return cppu::UnoType<XContainerListener>::get();
137 Container::Container(
138 const ::rtl::Reference< comphelper::RefCountedMutex > & refMutex,
139 const css::uno::Reference< css::sdbc::XConnection > & origin,
140 ConnectionSettings *pSettings,
141 const OUString &type)
142 : ContainerBase( refMutex->GetMutex() ),
143 m_xMutex( refMutex ),
144 m_pSettings( pSettings ),
145 m_origin( origin ),
146 m_type( type )
150 Any Container::getByName( const OUString& aName )
152 String2IntMap::const_iterator ii = m_name2index.find( aName );
153 if( ii == m_name2index.end() )
155 throw NoSuchElementException(
156 "Element " + aName + " unknown in " + m_type + "-Container",
157 *this );
159 OSL_ASSERT( ii->second >= 0 && ii->second < static_cast<int>(m_values.size()) );
160 return m_values[ ii->second ];
163 Sequence< OUString > Container::getElementNames( )
165 Sequence< OUString > ret( m_values.size() );
166 for( const auto& [rName, rIndex] : m_name2index )
168 // give element names in index order !
169 ret[rIndex] = rName;
171 return ret;
174 sal_Bool Container::hasByName( const OUString& aName )
176 return m_name2index.find( aName ) != m_name2index.end();
178 // Methods
179 Type Container::getElementType( )
181 return Type();
184 sal_Bool Container::hasElements( )
186 return ! m_name2index.empty();
189 Any Container::getByIndex( sal_Int32 Index )
191 if( Index < 0 || Index >= static_cast<sal_Int32>(m_values.size()) )
193 throw IndexOutOfBoundsException(
194 "Index " + OUString::number( Index )
195 + " out of range for " + m_type + "-Container, expected 0 <= x <= "
196 + OUString::number(m_values.size() -1),
197 *this );
199 return m_values[Index];
202 sal_Int32 Container::getCount()
204 return m_values.size();
207 namespace {
209 class ContainerEnumeration : public ::cppu::WeakImplHelper< XEnumeration >
211 std::vector< css::uno::Any > m_vec;
212 sal_Int32 m_index;
213 public:
214 explicit ContainerEnumeration( const std::vector< css::uno::Any > &vec )
215 : m_vec( vec ),
216 m_index( -1 )
219 public:
220 // XEnumeration
221 virtual sal_Bool SAL_CALL hasMoreElements( ) override;
222 virtual css::uno::Any SAL_CALL nextElement( ) override;
228 sal_Bool ContainerEnumeration::hasMoreElements()
230 return static_cast<int>(m_vec.size()) > m_index +1;
233 css::uno::Any ContainerEnumeration::nextElement()
235 if( ! hasMoreElements() )
237 throw NoSuchElementException(
238 "NoSuchElementException during enumeration", *this );
240 m_index ++;
241 return m_vec[m_index];
244 Reference< XEnumeration > Container::createEnumeration( )
246 return new ContainerEnumeration( m_values );
249 void Container::addRefreshListener(
250 const css::uno::Reference< css::util::XRefreshListener >& l )
252 rBHelper.addListener( cppu::UnoType<decltype(l)>::get() , l );
255 void Container::removeRefreshListener(
256 const css::uno::Reference< css::util::XRefreshListener >& l )
258 rBHelper.removeListener( cppu::UnoType<decltype(l)>::get() , l );
261 void Container::disposing()
263 m_origin.clear();
266 void Container::rename( const OUString &oldName, const OUString &newName )
268 Any newValue;
270 osl::MutexGuard guard ( m_xMutex->GetMutex() );
271 String2IntMap::iterator ii = m_name2index.find( oldName );
272 if( ii != m_name2index.end() )
274 sal_Int32 nIndex = ii->second;
275 newValue = m_values[nIndex];
276 m_name2index.erase( ii );
277 m_name2index[ newName ] = nIndex;
280 fire( ReplacedBroadcaster( *this, newName, newValue, oldName ) );
281 fire( RefreshedBroadcaster( *this ) );
284 void Container::dropByName( const OUString& elementName )
286 osl::MutexGuard guard( m_xMutex->GetMutex() );
287 String2IntMap::const_iterator ii = m_name2index.find( elementName );
288 if( ii == m_name2index.end() )
290 throw css::container::NoSuchElementException(
291 "Column " + elementName + " is unknown in "
292 + m_type + " container, so it can't be dropped",
293 *this );
295 dropByIndex( ii->second );
298 void Container::dropByIndex( sal_Int32 index )
300 osl::MutexGuard guard( m_xMutex->GetMutex() );
301 if( index < 0 || index >=static_cast<sal_Int32>(m_values.size()) )
303 throw css::lang::IndexOutOfBoundsException(
304 "Index out of range (allowed 0 to "
305 + OUString::number(m_values.size() -1)
306 + ", got " + OUString::number( index )
307 + ") in " + m_type,
308 *this );
311 OUString name;
312 String2IntMap::iterator ii = std::find_if(m_name2index.begin(), m_name2index.end(),
313 [&index](const String2IntMap::value_type& rEntry) { return rEntry.second == index; });
314 if (ii != m_name2index.end())
316 name = ii->first;
317 m_name2index.erase( ii );
320 for( int i = index +1 ; i < static_cast<int>(m_values.size()) ; i ++ )
322 m_values[i-1] = m_values[i];
324 // I know, this is expensive, but don't want to maintain another map ...
325 ii = std::find_if(m_name2index.begin(), m_name2index.end(),
326 [&i](const String2IntMap::value_type& rEntry) { return rEntry.second == i; });
327 if (ii != m_name2index.end())
329 ii->second = i-1;
332 m_values.resize( m_values.size() - 1 );
334 fire( RemovedBroadcaster( *this, name ) );
337 void Container::append(
338 const OUString & name,
339 const css::uno::Reference< css::beans::XPropertySet >& descriptor )
342 osl::MutexGuard guard( m_xMutex->GetMutex() );
344 if( hasByName( name ) )
346 throw css::container::ElementExistException(
347 "a " + m_type + " with name " + name + " already exists in this container",
348 *this );
351 int index = m_values.size();
352 m_values.push_back( makeAny( descriptor ) );
353 m_name2index[name] = index;
355 fire( InsertedBroadcaster( *this, name, makeAny( descriptor ) ) );
358 void Container::appendByDescriptor(
359 const css::uno::Reference< css::beans::XPropertySet >& descriptor)
361 append( extractStringProperty( descriptor, getStatics().NAME ), descriptor );
365 void Container::addContainerListener(
366 const css::uno::Reference< css::container::XContainerListener >& l )
368 rBHelper.addListener( cppu::UnoType<decltype(l)>::get() , l );
371 void Container::removeContainerListener(
372 const css::uno::Reference< css::container::XContainerListener >& l )
374 rBHelper.removeListener( cppu::UnoType<decltype(l)>::get() , l );
378 void Container::fire( const EventBroadcastHelper &helper )
380 cppu::OInterfaceContainerHelper *container = rBHelper.getContainer( helper.getType() );
381 if( !container )
382 return;
384 cppu::OInterfaceIteratorHelper iterator( * container );
385 while( iterator.hasMoreElements() )
389 helper.fire( static_cast<XEventListener *>(iterator.next()) );
391 catch ( css::uno::RuntimeException & )
393 OSL_ENSURE( false, "exception caught" );
394 // loose coupling, a runtime exception shall not break anything
395 // TODO: log away as warning !
397 catch( css::uno::Exception & )
399 OSL_ENSURE( false, "exception from listener flying through" );
400 throw;
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */