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< 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 0 : OHardRefMap(bool _bCase)
60 0 : : m_aNameMap(_bCase)
61 : {
62 0 : }
63 0 : virtual ~OHardRefMap()
64 : {
65 0 : }
66 :
67 0 : virtual void reserve(size_t nLength) SAL_OVERRIDE
68 : {
69 0 : m_aElements.reserve(nLength);
70 0 : }
71 :
72 0 : virtual bool exists(const OUString& _sName ) SAL_OVERRIDE
73 : {
74 0 : return m_aNameMap.find(_sName) != m_aNameMap.end();
75 : }
76 :
77 0 : virtual bool empty() SAL_OVERRIDE
78 : {
79 0 : return m_aNameMap.empty();
80 : }
81 :
82 0 : virtual void swapAll() SAL_OVERRIDE
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() SAL_OVERRIDE
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() SAL_OVERRIDE
102 : {
103 0 : m_aElements.clear();
104 0 : m_aNameMap.clear();
105 0 : }
106 :
107 0 : virtual void insert(const OUString& _sName,const ObjectType& _xObject) SAL_OVERRIDE
108 : {
109 0 : m_aElements.push_back(m_aNameMap.insert(m_aNameMap.begin(), ObjectEntry(_sName,_xObject)));
110 0 : }
111 :
112 0 : virtual void reFill(const TStringVector &_rVector) SAL_OVERRIDE
113 : {
114 : OSL_ENSURE(!m_aNameMap.size(),"OCollection::reFill: collection isn't empty");
115 0 : m_aElements.reserve(_rVector.size());
116 :
117 0 : for(TStringVector::const_iterator i=_rVector.begin(); i != _rVector.end();++i)
118 0 : m_aElements.push_back(m_aNameMap.insert(m_aNameMap.begin(), ObjectEntry(*i,ObjectType())));
119 0 : }
120 :
121 0 : virtual bool rename(const OUString& _sOldName, const OUString& _sNewName) SAL_OVERRIDE
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 0 : virtual sal_Int32 size() SAL_OVERRIDE
140 : {
141 0 : return static_cast<sal_Int32>(m_aNameMap.size());
142 : }
143 :
144 0 : virtual Sequence< OUString > getElementNames() SAL_OVERRIDE
145 : {
146 0 : Sequence< OUString > aNameList(m_aElements.size());
147 :
148 0 : OUString* pStringArray = aNameList.getArray();
149 0 : typename ::std::vector< ObjectIter >::const_iterator aEnd = m_aElements.end();
150 0 : for(typename ::std::vector< ObjectIter >::const_iterator aIter = m_aElements.begin(); aIter != aEnd;++aIter,++pStringArray)
151 0 : *pStringArray = (*aIter)->first;
152 :
153 0 : return aNameList;
154 : }
155 :
156 0 : virtual OUString getName(sal_Int32 _nIndex) SAL_OVERRIDE
157 : {
158 0 : return m_aElements[_nIndex]->first;
159 : }
160 :
161 0 : virtual void disposeAndErase(sal_Int32 _nIndex) SAL_OVERRIDE
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 : 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() SAL_OVERRIDE
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 0 : virtual sal_Int32 findColumn( const OUString& columnName ) SAL_OVERRIDE
189 : {
190 0 : ObjectIter aIter = m_aNameMap.find(columnName);
191 : OSL_ENSURE(aIter != m_aNameMap.end(),"findColumn:: Illegal name!");
192 0 : return m_aElements.size() - (m_aElements.end() - ::std::find(m_aElements.begin(),m_aElements.end(),aIter));
193 : }
194 :
195 0 : virtual OUString findColumnAtIndex( sal_Int32 _nIndex) SAL_OVERRIDE
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 0 : virtual ObjectType getObject(sal_Int32 _nIndex) SAL_OVERRIDE
202 : {
203 : OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
204 0 : return m_aElements[_nIndex]->second;
205 : }
206 :
207 0 : virtual ObjectType getObject(const OUString& columnName) SAL_OVERRIDE
208 : {
209 0 : return m_aNameMap.find(columnName)->second;
210 : }
211 :
212 0 : virtual void setObject(sal_Int32 _nIndex,const ObjectType& _xObject) SAL_OVERRIDE
213 : {
214 : OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
215 0 : m_aElements[_nIndex]->second = _xObject;
216 0 : }
217 :
218 0 : bool isCaseSensitive() const SAL_OVERRIDE
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 0 : OCollection::OCollection(::cppu::OWeakObject& _rParent
231 : , bool _bCase
232 : , ::osl::Mutex& _rMutex
233 : , const TStringVector &_rVector
234 : , bool _bUseIndexOnly
235 : , bool _bUseHardRef)
236 : :m_aContainerListeners(_rMutex)
237 : ,m_aRefreshListeners(_rMutex)
238 : ,m_rParent(_rParent)
239 : ,m_rMutex(_rMutex)
240 0 : ,m_bUseIndexOnly(_bUseIndexOnly)
241 : {
242 0 : if ( _bUseHardRef )
243 : {
244 0 : m_pElements.reset(new OHardRefMap< ObjectType >(_bCase));
245 : }
246 : else
247 : {
248 0 : m_pElements.reset(new OHardRefMap< WeakReference< XPropertySet> >(_bCase));
249 : }
250 0 : m_pElements->reFill(_rVector);
251 0 : }
252 :
253 0 : OCollection::~OCollection()
254 : {
255 0 : }
256 :
257 0 : Any SAL_CALL OCollection::queryInterface( const Type & rType ) throw (RuntimeException, std::exception)
258 : {
259 0 : if ( m_bUseIndexOnly && rType == ::getCppuType(static_cast< Reference< XNameAccess > *> (NULL)) )
260 : {
261 0 : return Any();
262 : }
263 0 : return OCollectionBase::queryInterface( rType );
264 : }
265 :
266 0 : Sequence< Type > SAL_CALL OCollection::getTypes() throw (RuntimeException, std::exception)
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 0 : Any SAL_CALL OCollection::getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
310 : {
311 0 : ::osl::MutexGuard aGuard(m_rMutex);
312 0 : if (Index < 0 || Index >= m_pElements->size() )
313 0 : throw IndexOutOfBoundsException(OUString::number(Index),static_cast<XTypeProvider*>(this));
314 :
315 0 : return makeAny(getObject(Index));
316 : }
317 :
318 0 : Any SAL_CALL OCollection::getByName( const OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
319 : {
320 0 : ::osl::MutexGuard aGuard(m_rMutex);
321 :
322 0 : if ( !m_pElements->exists(aName) )
323 : {
324 0 : ::connectivity::SharedResources aResources;
325 : const 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 0 : return makeAny(getObject(m_pElements->findColumn(aName)));
333 : }
334 :
335 0 : Sequence< OUString > SAL_CALL OCollection::getElementNames( ) throw(RuntimeException, std::exception)
336 : {
337 0 : ::osl::MutexGuard aGuard(m_rMutex);
338 0 : return m_pElements->getElementNames();
339 : }
340 :
341 0 : void SAL_CALL OCollection::refresh( ) throw(RuntimeException, std::exception)
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, std::exception)
359 : {
360 0 : ::osl::MutexGuard aGuard(m_rMutex);
361 :
362 0 : return createDescriptor();
363 : }
364 :
365 0 : OUString OCollection::getNameForObject(const ObjectType& _xObject)
366 : {
367 : OSL_ENSURE(_xObject.is(),"OCollection::getNameForObject: Object is NULL!");
368 0 : 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, std::exception)
375 : {
376 0 : ::osl::ClearableMutexGuard aGuard(m_rMutex);
377 :
378 0 : 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( 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 OUString& elementName ) throw(SQLException, NoSuchElementException, RuntimeException, std::exception)
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, std::exception)
413 : {
414 0 : ::osl::MutexGuard aGuard(m_rMutex);
415 0 : if(index <0 || index >= getCount())
416 0 : throw IndexOutOfBoundsException(OUString::number(index),static_cast<XTypeProvider*>(this));
417 :
418 0 : dropImpl(index);
419 0 : }
420 :
421 0 : void OCollection::dropImpl(sal_Int32 _nIndex, bool _bReallyDrop)
422 : {
423 0 : 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 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 0 : sal_Int32 SAL_CALL OCollection::findColumn( const OUString& columnName ) throw(SQLException, RuntimeException, std::exception)
444 : {
445 0 : if ( !m_pElements->exists(columnName) )
446 : {
447 0 : ::dbtools::throwInvalidColumnException( columnName, static_cast< XIndexAccess*>(this) );
448 : assert(false);
449 : }
450 :
451 0 : return m_pElements->findColumn(columnName) + 1; // because columns start at one
452 : }
453 :
454 0 : Reference< XEnumeration > SAL_CALL OCollection::createEnumeration( ) throw(RuntimeException, std::exception)
455 : {
456 0 : ::osl::MutexGuard aGuard(m_rMutex);
457 0 : return new OEnumerationByIndex( static_cast< XIndexAccess*>(this));
458 : }
459 :
460 0 : void SAL_CALL OCollection::addContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException, std::exception)
461 : {
462 0 : m_aContainerListeners.addInterface(_rxListener);
463 0 : }
464 :
465 :
466 0 : void SAL_CALL OCollection::removeContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException, std::exception)
467 : {
468 0 : m_aContainerListeners.removeInterface(_rxListener);
469 0 : }
470 :
471 0 : void SAL_CALL OCollection::acquire() throw()
472 : {
473 0 : m_rParent.acquire();
474 0 : }
475 :
476 0 : void SAL_CALL OCollection::release() throw()
477 : {
478 0 : m_rParent.release();
479 0 : }
480 :
481 0 : Type SAL_CALL OCollection::getElementType( ) throw(RuntimeException, std::exception)
482 : {
483 0 : return::getCppuType(static_cast< Reference< XPropertySet>*>(NULL));
484 : }
485 :
486 0 : sal_Bool SAL_CALL OCollection::hasElements( ) throw(RuntimeException, std::exception)
487 : {
488 0 : ::osl::MutexGuard aGuard(m_rMutex);
489 0 : return !m_pElements->empty();
490 : }
491 :
492 0 : sal_Int32 SAL_CALL OCollection::getCount( ) throw(RuntimeException, std::exception)
493 : {
494 0 : ::osl::MutexGuard aGuard(m_rMutex);
495 0 : return m_pElements->size();
496 : }
497 :
498 0 : sal_Bool SAL_CALL OCollection::hasByName( const OUString& aName ) throw(RuntimeException, std::exception)
499 : {
500 0 : ::osl::MutexGuard aGuard(m_rMutex);
501 0 : return m_pElements->exists(aName);
502 : }
503 :
504 0 : void SAL_CALL OCollection::addRefreshListener( const Reference< XRefreshListener >& l ) throw(RuntimeException, std::exception)
505 : {
506 0 : m_aRefreshListeners.addInterface(l);
507 0 : }
508 :
509 0 : void SAL_CALL OCollection::removeRefreshListener( const Reference< XRefreshListener >& l ) throw(RuntimeException, std::exception)
510 : {
511 0 : m_aRefreshListeners.removeInterface(l);
512 0 : }
513 :
514 0 : void OCollection::insertElement(const OUString& _sElementName,const ObjectType& _xElement)
515 : {
516 : OSL_ENSURE(!m_pElements->exists(_sElementName),"Element already exists");
517 0 : if ( !m_pElements->exists(_sElementName) )
518 0 : m_pElements->insert(_sElementName,_xElement);
519 0 : }
520 :
521 0 : void OCollection::renameObject(const OUString& _sOldName, const OUString& _sNewName)
522 : {
523 : OSL_ENSURE(m_pElements->exists(_sOldName),"Element doesn't exist");
524 : OSL_ENSURE(!m_pElements->exists(_sNewName),"Element already exists");
525 : OSL_ENSURE(!_sNewName.isEmpty(),"New name must not be empty!");
526 : OSL_ENSURE(!_sOldName.isEmpty(),"Old name must not be empty!");
527 :
528 0 : if ( m_pElements->rename(_sOldName,_sNewName) )
529 : {
530 0 : ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(_sNewName), makeAny(m_pElements->getObject(_sNewName)),makeAny(_sOldName));
531 : // note that xExistent may be empty, in case somebody removed the data source while it is not alive at this moment
532 0 : OInterfaceIteratorHelper aListenerLoop(m_aContainerListeners);
533 0 : while (aListenerLoop.hasMoreElements())
534 0 : static_cast<XContainerListener*>(aListenerLoop.next())->elementReplaced(aEvent);
535 : }
536 0 : }
537 :
538 0 : ObjectType OCollection::getObject(sal_Int32 _nIndex)
539 : {
540 0 : ObjectType xName = m_pElements->getObject(_nIndex);
541 0 : if ( !xName.is() )
542 : {
543 : try
544 : {
545 0 : xName = createObject(m_pElements->getName(_nIndex));
546 : }
547 0 : catch(const SQLException& e)
548 : {
549 : try
550 : {
551 0 : dropImpl(_nIndex,false);
552 : }
553 0 : catch(const Exception& )
554 : {
555 : }
556 0 : throw WrappedTargetException(e.Message,static_cast<XTypeProvider*>(this),makeAny(e));
557 : }
558 0 : m_pElements->setObject(_nIndex,xName);
559 : }
560 0 : return xName;
561 : }
562 :
563 0 : void OCollection::disposeElements()
564 : {
565 0 : m_pElements->disposeElements();
566 0 : }
567 :
568 0 : Reference< XPropertySet > OCollection::createDescriptor()
569 : {
570 : OSL_FAIL("Need to be overloaded when used!");
571 0 : throw SQLException();
572 : }
573 :
574 0 : ObjectType OCollection::cloneDescriptor( const ObjectType& _descriptor )
575 : {
576 0 : ObjectType xNewDescriptor( createDescriptor() );
577 0 : ::comphelper::copyProperties( _descriptor, xNewDescriptor );
578 0 : return xNewDescriptor;
579 : }
580 :
581 0 : ObjectType OCollection::appendObject( const OUString& /*_rForName*/, const Reference< XPropertySet >& descriptor )
582 : {
583 0 : return cloneDescriptor( descriptor );
584 : }
585 :
586 0 : void OCollection::dropObject(sal_Int32 /*_nPos*/, const OUString& /*_sElementName*/)
587 : {
588 0 : }
589 :
590 :
591 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|