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 :
21 : #include <algorithm>
22 : #include <stdio.h>
23 : #include "connectivity/sdbcx/VCollection.hxx"
24 : #include "connectivity/sdbcx/VDescriptor.hxx"
25 : #include "connectivity/dbexception.hxx"
26 : #include <comphelper/enumhelper.hxx>
27 : #include <comphelper/container.hxx>
28 : #include <comphelper/types.hxx>
29 : #include <comphelper/property.hxx>
30 : #include "TConnection.hxx"
31 : #include <rtl/ustrbuf.hxx>
32 : #include "resource/common_res.hrc"
33 : #include "resource/sharedresources.hxx"
34 :
35 : using namespace connectivity::sdbcx;
36 : using namespace connectivity;
37 : using namespace comphelper;
38 : using namespace ::cppu;
39 : using namespace ::com::sun::star::beans;
40 : using namespace ::com::sun::star::uno;
41 : using namespace ::com::sun::star::lang;
42 : using namespace ::com::sun::star::sdbc;
43 : using namespace ::com::sun::star::container;
44 : using namespace ::com::sun::star::util;
45 :
46 : namespace
47 : {
48 : template < typename T> class OHardRefMap : public connectivity::sdbcx::IObjectCollection
49 : {
50 : typedef ::std::multimap< ::rtl::OUString, T , ::comphelper::UStringMixLess> ObjectMap;
51 : typedef typename ObjectMap::iterator ObjectIter;
52 : typedef typename ObjectMap::value_type ObjectEntry;
53 :
54 : // private:
55 : // this combination of map and vector is used to have a fast name and index access
56 : ::std::vector< ObjectIter > m_aElements; // hold the iterators which point to map
57 : ObjectMap m_aNameMap; // hold the elements and a name
58 : public:
59 4 : OHardRefMap(sal_Bool _bCase)
60 4 : : m_aNameMap(_bCase ? true : false)
61 : {
62 4 : }
63 0 : virtual ~OHardRefMap()
64 : {
65 0 : }
66 :
67 0 : virtual void reserve(size_t nLength)
68 : {
69 0 : m_aElements.reserve(nLength);
70 0 : }
71 : // -----------------------------------------------------------------------------
72 13 : virtual bool exists(const ::rtl::OUString& _sName )
73 : {
74 13 : return m_aNameMap.find(_sName) != m_aNameMap.end();
75 : }
76 : // -----------------------------------------------------------------------------
77 0 : virtual bool empty()
78 : {
79 0 : return m_aNameMap.empty();
80 : }
81 : // -----------------------------------------------------------------------------
82 0 : virtual void swapAll()
83 : {
84 0 : ::std::vector< ObjectIter >(m_aElements).swap(m_aElements);
85 0 : ObjectMap(m_aNameMap).swap(m_aNameMap);
86 0 : }
87 : // -----------------------------------------------------------------------------
88 0 : virtual void swap()
89 : {
90 0 : ::std::vector< ObjectIter >().swap(m_aElements);
91 :
92 : OSL_ENSURE( m_aNameMap.empty(), "swap: what did disposeElements do?" );
93 0 : ObjectMap( m_aNameMap ).swap( m_aNameMap );
94 : // Note that it's /important/ to construct the new ObjectMap from m_aNameMap before
95 : // swapping. This way, it's ensured that the compare object held by these maps is preserved
96 : // during the swap. If we would not do this, the UStringMixLess instance which is used would be
97 : // default constructed (instead of being constructed from the same instance in m_aNameMap), and
98 : // it's case-sensitive flag would have an unpredictable value.
99 0 : }
100 : // -----------------------------------------------------------------------------
101 0 : virtual void clear()
102 : {
103 0 : m_aElements.clear();
104 0 : m_aNameMap.clear();
105 0 : }
106 : // -----------------------------------------------------------------------------
107 0 : virtual void insert(const ::rtl::OUString& _sName,const ObjectType& _xObject)
108 : {
109 0 : m_aElements.push_back(m_aNameMap.insert(m_aNameMap.begin(), ObjectEntry(_sName,_xObject)));
110 0 : }
111 : // -----------------------------------------------------------------------------
112 4 : virtual void reFill(const TStringVector &_rVector)
113 : {
114 : OSL_ENSURE(!m_aNameMap.size(),"OCollection::reFill: collection isn't empty");
115 4 : m_aElements.reserve(_rVector.size());
116 :
117 84 : for(TStringVector::const_iterator i=_rVector.begin(); i != _rVector.end();++i)
118 80 : m_aElements.push_back(m_aNameMap.insert(m_aNameMap.begin(), ObjectEntry(*i,ObjectType())));
119 4 : }
120 : // -----------------------------------------------------------------------------
121 0 : virtual bool rename(const ::rtl::OUString _sOldName,const ::rtl::OUString _sNewName)
122 : {
123 0 : bool bRet = false;
124 0 : ObjectIter aIter = m_aNameMap.find(_sOldName);
125 0 : if ( aIter != m_aNameMap.end() )
126 : {
127 0 : typename ::std::vector< ObjectIter >::iterator aFind = ::std::find(m_aElements.begin(),m_aElements.end(),aIter);
128 0 : if(m_aElements.end() != aFind)
129 : {
130 0 : (*aFind) = m_aNameMap.insert(m_aNameMap.begin(), ObjectEntry(_sNewName,(*aFind)->second));
131 0 : m_aNameMap.erase(aIter);
132 :
133 0 : bRet = true;
134 : }
135 : }
136 0 : return bRet;
137 : }
138 : // -----------------------------------------------------------------------------
139 150 : virtual sal_Int32 size()
140 : {
141 150 : return static_cast<sal_Int32>(m_aNameMap.size());
142 : }
143 : // -----------------------------------------------------------------------------
144 2 : virtual Sequence< ::rtl::OUString > getElementNames()
145 : {
146 2 : Sequence< ::rtl::OUString > aNameList(m_aElements.size());
147 :
148 2 : ::rtl::OUString* pStringArray = aNameList.getArray();
149 2 : typename ::std::vector< ObjectIter >::const_iterator aEnd = m_aElements.end();
150 76 : for(typename ::std::vector< ObjectIter >::const_iterator aIter = m_aElements.begin(); aIter != aEnd;++aIter,++pStringArray)
151 74 : *pStringArray = (*aIter)->first;
152 :
153 2 : return aNameList;
154 : }
155 : // -----------------------------------------------------------------------------
156 76 : virtual ::rtl::OUString getName(sal_Int32 _nIndex)
157 : {
158 76 : return m_aElements[_nIndex]->first;
159 : }
160 : // -----------------------------------------------------------------------------
161 0 : virtual void disposeAndErase(sal_Int32 _nIndex)
162 : {
163 : OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
164 0 : Reference<XComponent> xComp(m_aElements[_nIndex]->second.get(),UNO_QUERY);
165 0 : ::comphelper::disposeComponent(xComp);
166 0 : m_aElements[_nIndex]->second = T();
167 :
168 0 : ::rtl::OUString sName = m_aElements[_nIndex]->first;
169 0 : m_aElements.erase(m_aElements.begin()+_nIndex);
170 0 : m_aNameMap.erase(sName);
171 0 : }
172 : // -----------------------------------------------------------------------------
173 0 : virtual void disposeElements()
174 : {
175 0 : for( ObjectIter aIter = m_aNameMap.begin(); aIter != m_aNameMap.end(); ++aIter)
176 : {
177 0 : Reference<XComponent> xComp(aIter->second.get(),UNO_QUERY);
178 0 : if ( xComp.is() )
179 : {
180 0 : ::comphelper::disposeComponent(xComp);
181 0 : (*aIter).second = T();
182 : }
183 : }
184 0 : m_aElements.clear();
185 0 : m_aNameMap.clear();
186 0 : }
187 : // -----------------------------------------------------------------------------
188 6 : virtual sal_Int32 findColumn( const ::rtl::OUString& columnName )
189 : {
190 6 : ObjectIter aIter = m_aNameMap.find(columnName);
191 : OSL_ENSURE(aIter != m_aNameMap.end(),"findColumn:: Illegal name!");
192 6 : return m_aElements.size() - (m_aElements.end() - ::std::find(m_aElements.begin(),m_aElements.end(),aIter));
193 : }
194 : // -----------------------------------------------------------------------------
195 0 : virtual ::rtl::OUString findColumnAtIndex( sal_Int32 _nIndex)
196 : {
197 : OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
198 0 : return m_aElements[_nIndex]->first;
199 : }
200 : // -----------------------------------------------------------------------------
201 153 : virtual ObjectType getObject(sal_Int32 _nIndex)
202 : {
203 : OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
204 153 : return m_aElements[_nIndex]->second;
205 : }
206 : // -----------------------------------------------------------------------------
207 0 : virtual ObjectType getObject(const ::rtl::OUString& columnName)
208 : {
209 0 : return m_aNameMap.find(columnName)->second;
210 : }
211 : // -----------------------------------------------------------------------------
212 76 : virtual void setObject(sal_Int32 _nIndex,const ObjectType& _xObject)
213 : {
214 : OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
215 76 : m_aElements[_nIndex]->second = _xObject;
216 76 : }
217 : // -----------------------------------------------------------------------------
218 0 : sal_Bool isCaseSensitive() const
219 : {
220 0 : return m_aNameMap.key_comp().isCaseSensitive();
221 : }
222 : // -----------------------------------------------------------------------------
223 : };
224 : }
225 :
226 0 : IObjectCollection::~IObjectCollection() {}
227 :
228 0 : IMPLEMENT_SERVICE_INFO(OCollection,"com.sun.star.sdbcx.VContainer" , "com.sun.star.sdbcx.Container")
229 :
230 4 : OCollection::OCollection(::cppu::OWeakObject& _rParent
231 : , sal_Bool _bCase
232 : , ::osl::Mutex& _rMutex
233 : , const TStringVector &_rVector
234 : , sal_Bool _bUseIndexOnly
235 : , sal_Bool _bUseHardRef)
236 : :m_aContainerListeners(_rMutex)
237 : ,m_aRefreshListeners(_rMutex)
238 : ,m_rParent(_rParent)
239 : ,m_rMutex(_rMutex)
240 4 : ,m_bUseIndexOnly(_bUseIndexOnly)
241 : {
242 4 : if ( _bUseHardRef )
243 : {
244 4 : m_pElements.reset(new OHardRefMap< ObjectType >(_bCase));
245 : }
246 : else
247 : {
248 0 : m_pElements.reset(new OHardRefMap< WeakReference< XPropertySet> >(_bCase));
249 : }
250 4 : m_pElements->reFill(_rVector);
251 4 : }
252 : // -------------------------------------------------------------------------
253 0 : OCollection::~OCollection()
254 : {
255 0 : }
256 : // -----------------------------------------------------------------------------
257 7 : Any SAL_CALL OCollection::queryInterface( const Type & rType ) throw (RuntimeException)
258 : {
259 7 : if ( m_bUseIndexOnly && rType == ::getCppuType(static_cast< Reference< XNameAccess > *> (NULL)) )
260 : {
261 0 : return Any();
262 : }
263 7 : return OCollectionBase::queryInterface( rType );
264 : }
265 : // -----------------------------------------------------------------------------
266 0 : Sequence< Type > SAL_CALL OCollection::getTypes() throw (RuntimeException)
267 : {
268 0 : if ( m_bUseIndexOnly )
269 : {
270 0 : Sequence< Type > aTypes(OCollectionBase::getTypes());
271 0 : Type* pBegin = aTypes.getArray();
272 0 : Type* pEnd = pBegin + aTypes.getLength();
273 :
274 0 : ::std::vector<Type> aOwnTypes;
275 0 : aOwnTypes.reserve(aTypes.getLength());
276 0 : Type aType = ::getCppuType(static_cast< Reference<XNameAccess> *>(NULL));
277 0 : for(;pBegin != pEnd; ++pBegin)
278 : {
279 0 : if ( *pBegin != aType )
280 0 : aOwnTypes.push_back(*pBegin);
281 : }
282 0 : Type* pTypes = aOwnTypes.empty() ? 0 : &aOwnTypes[0];
283 0 : return Sequence< Type >(pTypes,aOwnTypes.size());
284 : }
285 0 : return OCollectionBase::getTypes( );
286 : }
287 : // -------------------------------------------------------------------------
288 0 : void OCollection::clear_NoDispose()
289 : {
290 0 : ::osl::MutexGuard aGuard(m_rMutex);
291 :
292 0 : m_pElements->clear();
293 0 : m_pElements->swapAll();
294 0 : }
295 :
296 : // -------------------------------------------------------------------------
297 0 : void OCollection::disposing(void)
298 : {
299 0 : m_aContainerListeners.disposeAndClear(EventObject(static_cast<XTypeProvider*>(this)));
300 0 : m_aRefreshListeners.disposeAndClear(EventObject(static_cast<XTypeProvider*>(this)));
301 :
302 0 : ::osl::MutexGuard aGuard(m_rMutex);
303 :
304 0 : disposeElements();
305 :
306 0 : m_pElements->swap();
307 0 : }
308 : // -------------------------------------------------------------------------
309 148 : Any SAL_CALL OCollection::getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
310 : {
311 148 : ::osl::MutexGuard aGuard(m_rMutex);
312 148 : if (Index < 0 || Index >= m_pElements->size() )
313 0 : throw IndexOutOfBoundsException(::rtl::OUString::valueOf(Index),static_cast<XTypeProvider*>(this));
314 :
315 148 : return makeAny(getObject(Index));
316 : }
317 : // -------------------------------------------------------------------------
318 5 : Any SAL_CALL OCollection::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
319 : {
320 5 : ::osl::MutexGuard aGuard(m_rMutex);
321 :
322 5 : if ( !m_pElements->exists(aName) )
323 : {
324 0 : ::connectivity::SharedResources aResources;
325 : const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(
326 : STR_NO_ELEMENT_NAME,
327 : "$name$", aName
328 0 : ) );
329 0 : throw NoSuchElementException( sError, static_cast< XTypeProvider* >( this ) );
330 : }
331 :
332 5 : return makeAny(getObject(m_pElements->findColumn(aName)));
333 : }
334 : // -------------------------------------------------------------------------
335 2 : Sequence< ::rtl::OUString > SAL_CALL OCollection::getElementNames( ) throw(RuntimeException)
336 : {
337 2 : ::osl::MutexGuard aGuard(m_rMutex);
338 2 : return m_pElements->getElementNames();
339 : }
340 : // -------------------------------------------------------------------------
341 0 : void SAL_CALL OCollection::refresh( ) throw(RuntimeException)
342 : {
343 0 : ::osl::MutexGuard aGuard(m_rMutex);
344 :
345 0 : disposeElements();
346 :
347 0 : impl_refresh();
348 0 : EventObject aEvt(static_cast<XTypeProvider*>(this));
349 0 : m_aRefreshListeners.notifyEach( &XRefreshListener::refreshed, aEvt );
350 0 : }
351 : // -----------------------------------------------------------------------------
352 0 : void OCollection::reFill(const TStringVector &_rVector)
353 : {
354 0 : m_pElements->reFill(_rVector);
355 0 : }
356 : // -------------------------------------------------------------------------
357 : // XDataDescriptorFactory
358 0 : Reference< XPropertySet > SAL_CALL OCollection::createDataDescriptor( ) throw(RuntimeException)
359 : {
360 0 : ::osl::MutexGuard aGuard(m_rMutex);
361 :
362 0 : return createDescriptor();
363 : }
364 : // -----------------------------------------------------------------------------
365 0 : ::rtl::OUString OCollection::getNameForObject(const ObjectType& _xObject)
366 : {
367 : OSL_ENSURE(_xObject.is(),"OCollection::getNameForObject: Object is NULL!");
368 0 : ::rtl::OUString sName;
369 0 : _xObject->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= sName;
370 0 : return sName;
371 : }
372 : // -------------------------------------------------------------------------
373 : // XAppend
374 0 : void SAL_CALL OCollection::appendByDescriptor( const Reference< XPropertySet >& descriptor ) throw(SQLException, ElementExistException, RuntimeException)
375 : {
376 0 : ::osl::ClearableMutexGuard aGuard(m_rMutex);
377 :
378 0 : ::rtl::OUString sName = getNameForObject( descriptor );
379 :
380 0 : if ( m_pElements->exists(sName) )
381 0 : throw ElementExistException(sName,static_cast<XTypeProvider*>(this));
382 :
383 0 : ObjectType xNewlyCreated = appendObject( sName, descriptor );
384 0 : if ( !xNewlyCreated.is() )
385 0 : throw RuntimeException();
386 :
387 0 : ODescriptor* pDescriptor = ODescriptor::getImplementation( xNewlyCreated );
388 0 : if ( pDescriptor )
389 0 : pDescriptor->setNew( sal_False );
390 :
391 0 : sName = getNameForObject( xNewlyCreated );
392 0 : if ( !m_pElements->exists( sName ) ) // this may happen when the drived class included it itself
393 0 : m_pElements->insert( sName, xNewlyCreated );
394 :
395 : // notify our container listeners
396 0 : ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(sName), makeAny(xNewlyCreated), Any());
397 0 : aGuard.clear();
398 0 : m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
399 0 : }
400 : // -------------------------------------------------------------------------
401 : // XDrop
402 0 : void SAL_CALL OCollection::dropByName( const ::rtl::OUString& elementName ) throw(SQLException, NoSuchElementException, RuntimeException)
403 : {
404 0 : ::osl::MutexGuard aGuard(m_rMutex);
405 :
406 0 : if ( !m_pElements->exists(elementName) )
407 0 : throw NoSuchElementException(elementName,static_cast<XTypeProvider*>(this));
408 :
409 0 : dropImpl(m_pElements->findColumn(elementName));
410 0 : }
411 : // -------------------------------------------------------------------------
412 0 : void SAL_CALL OCollection::dropByIndex( sal_Int32 index ) throw(SQLException, IndexOutOfBoundsException, RuntimeException)
413 : {
414 0 : ::osl::MutexGuard aGuard(m_rMutex);
415 0 : if(index <0 || index >= getCount())
416 0 : throw IndexOutOfBoundsException(::rtl::OUString::valueOf(index),static_cast<XTypeProvider*>(this));
417 :
418 0 : dropImpl(index);
419 0 : }
420 : // -----------------------------------------------------------------------------
421 0 : void OCollection::dropImpl(sal_Int32 _nIndex,sal_Bool _bReallyDrop)
422 : {
423 0 : ::rtl::OUString elementName = m_pElements->getName(_nIndex);
424 :
425 0 : if ( _bReallyDrop )
426 0 : dropObject(_nIndex,elementName);
427 :
428 0 : m_pElements->disposeAndErase(_nIndex);
429 :
430 : // notify our container listeners
431 0 : notifyElementRemoved(elementName);
432 0 : }
433 : // -----------------------------------------------------------------------------
434 0 : void OCollection::notifyElementRemoved(const ::rtl::OUString& _sName)
435 : {
436 0 : ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(_sName), Any(), Any());
437 : // note that xExistent may be empty, in case somebody removed the data source while it is not alive at this moment
438 0 : OInterfaceIteratorHelper aListenerLoop(m_aContainerListeners);
439 0 : while (aListenerLoop.hasMoreElements())
440 0 : static_cast<XContainerListener*>(aListenerLoop.next())->elementRemoved(aEvent);
441 0 : }
442 : // -------------------------------------------------------------------------
443 1 : sal_Int32 SAL_CALL OCollection::findColumn( const ::rtl::OUString& columnName ) throw(SQLException, RuntimeException)
444 : {
445 1 : if ( !m_pElements->exists(columnName) )
446 : {
447 0 : ::connectivity::SharedResources aResources;
448 : const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(
449 : STR_UNKNOWN_COLUMN_NAME,
450 : "$columnname$", columnName
451 0 : ) );
452 0 : ::dbtools::throwGenericSQLException(sError,static_cast< XIndexAccess*>(this));
453 : }
454 :
455 1 : return m_pElements->findColumn(columnName) + 1; // because columns start at one
456 : }
457 : // -------------------------------------------------------------------------
458 0 : Reference< XEnumeration > SAL_CALL OCollection::createEnumeration( ) throw(RuntimeException)
459 : {
460 0 : ::osl::MutexGuard aGuard(m_rMutex);
461 0 : return new OEnumerationByIndex( static_cast< XIndexAccess*>(this));
462 : }
463 : // -----------------------------------------------------------------------------
464 0 : void SAL_CALL OCollection::addContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
465 : {
466 0 : m_aContainerListeners.addInterface(_rxListener);
467 0 : }
468 :
469 : //------------------------------------------------------------------------------
470 0 : void SAL_CALL OCollection::removeContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
471 : {
472 0 : m_aContainerListeners.removeInterface(_rxListener);
473 0 : }
474 : // -----------------------------------------------------------------------------
475 24 : void SAL_CALL OCollection::acquire() throw()
476 : {
477 24 : m_rParent.acquire();
478 24 : }
479 : // -----------------------------------------------------------------------------
480 18 : void SAL_CALL OCollection::release() throw()
481 : {
482 18 : m_rParent.release();
483 18 : }
484 : // -----------------------------------------------------------------------------
485 0 : Type SAL_CALL OCollection::getElementType( ) throw(RuntimeException)
486 : {
487 0 : return::getCppuType(static_cast< Reference< XPropertySet>*>(NULL));
488 : }
489 : // -----------------------------------------------------------------------------
490 0 : sal_Bool SAL_CALL OCollection::hasElements( ) throw(RuntimeException)
491 : {
492 0 : ::osl::MutexGuard aGuard(m_rMutex);
493 0 : return !m_pElements->empty();
494 : }
495 : // -----------------------------------------------------------------------------
496 2 : sal_Int32 SAL_CALL OCollection::getCount( ) throw(RuntimeException)
497 : {
498 2 : ::osl::MutexGuard aGuard(m_rMutex);
499 2 : return m_pElements->size();
500 : }
501 : // -----------------------------------------------------------------------------
502 7 : sal_Bool SAL_CALL OCollection::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException)
503 : {
504 7 : ::osl::MutexGuard aGuard(m_rMutex);
505 7 : return m_pElements->exists(aName);
506 : }
507 : // -----------------------------------------------------------------------------
508 0 : void SAL_CALL OCollection::addRefreshListener( const Reference< XRefreshListener >& l ) throw(RuntimeException)
509 : {
510 0 : m_aRefreshListeners.addInterface(l);
511 0 : }
512 : // -----------------------------------------------------------------------------
513 0 : void SAL_CALL OCollection::removeRefreshListener( const Reference< XRefreshListener >& l ) throw(RuntimeException)
514 : {
515 0 : m_aRefreshListeners.removeInterface(l);
516 0 : }
517 : // -----------------------------------------------------------------------------
518 0 : void OCollection::insertElement(const ::rtl::OUString& _sElementName,const ObjectType& _xElement)
519 : {
520 : OSL_ENSURE(!m_pElements->exists(_sElementName),"Element already exists");
521 0 : if ( !m_pElements->exists(_sElementName) )
522 0 : m_pElements->insert(_sElementName,_xElement);
523 0 : }
524 : // -----------------------------------------------------------------------------
525 0 : void OCollection::renameObject(const ::rtl::OUString _sOldName,const ::rtl::OUString _sNewName)
526 : {
527 : OSL_ENSURE(m_pElements->exists(_sOldName),"Element doesn't exist");
528 : OSL_ENSURE(!m_pElements->exists(_sNewName),"Element already exists");
529 : OSL_ENSURE(!_sNewName.isEmpty(),"New name must not be empty!");
530 : OSL_ENSURE(!_sOldName.isEmpty(),"Old name must not be empty!");
531 :
532 0 : if ( m_pElements->rename(_sOldName,_sNewName) )
533 : {
534 0 : ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(_sNewName), makeAny(m_pElements->getObject(_sNewName)),makeAny(_sOldName));
535 : // note that xExistent may be empty, in case somebody removed the data source while it is not alive at this moment
536 0 : OInterfaceIteratorHelper aListenerLoop(m_aContainerListeners);
537 0 : while (aListenerLoop.hasMoreElements())
538 0 : static_cast<XContainerListener*>(aListenerLoop.next())->elementReplaced(aEvent);
539 : }
540 0 : }
541 : // -----------------------------------------------------------------------------
542 153 : ObjectType OCollection::getObject(sal_Int32 _nIndex)
543 : {
544 153 : ObjectType xName = m_pElements->getObject(_nIndex);
545 153 : if ( !xName.is() )
546 : {
547 : try
548 : {
549 76 : xName = createObject(m_pElements->getName(_nIndex));
550 : }
551 0 : catch(const SQLException& e)
552 : {
553 : try
554 : {
555 0 : dropImpl(_nIndex,sal_False);
556 : }
557 0 : catch(const Exception& )
558 : {
559 : }
560 0 : throw WrappedTargetException(e.Message,static_cast<XTypeProvider*>(this),makeAny(e));
561 : }
562 76 : m_pElements->setObject(_nIndex,xName);
563 : }
564 153 : return xName;
565 : }
566 : // -----------------------------------------------------------------------------
567 0 : void OCollection::disposeElements()
568 : {
569 0 : m_pElements->disposeElements();
570 0 : }
571 : // -----------------------------------------------------------------------------
572 0 : Reference< XPropertySet > OCollection::createDescriptor()
573 : {
574 : OSL_ASSERT(!"Need to be overloaded when used!");
575 0 : throw SQLException();
576 : }
577 : // -----------------------------------------------------------------------------
578 0 : ObjectType OCollection::cloneDescriptor( const ObjectType& _descriptor )
579 : {
580 0 : ObjectType xNewDescriptor( createDescriptor() );
581 0 : ::comphelper::copyProperties( _descriptor, xNewDescriptor );
582 0 : return xNewDescriptor;
583 : }
584 : // -----------------------------------------------------------------------------
585 0 : ObjectType OCollection::appendObject( const ::rtl::OUString& /*_rForName*/, const Reference< XPropertySet >& descriptor )
586 : {
587 0 : return cloneDescriptor( descriptor );
588 : }
589 : // -----------------------------------------------------------------------------
590 0 : void OCollection::dropObject(sal_Int32 /*_nPos*/,const ::rtl::OUString /*_sElementName*/)
591 : {
592 0 : }
593 : // -----------------------------------------------------------------------------
594 :
595 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|