xref: /trunk/main/dbaccess/source/core/dataaccess/definitioncontainer.cxx (revision 3ce6c2dd3860afd353ceca3849779821e9b9f6f5)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26 
27 #ifndef _DBA_CORE_DEFINITIONCONTAINER_HXX_
28 #include "definitioncontainer.hxx"
29 #endif
30 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC
31 #include "dbastrings.hrc"
32 #endif
33 #ifndef _DBASHARED_APITOOLS_HXX_
34 #include "apitools.hxx"
35 #endif
36 #ifndef _DBA_CORE_RESOURCE_HXX_
37 #include "core_resource.hxx"
38 #endif
39 #ifndef _DBA_CORE_RESOURCE_HRC_
40 #include "core_resource.hrc"
41 #endif
42 
43 #ifndef _TOOLS_DEBUG_HXX
44 #include <tools/debug.hxx>
45 #endif
46 #ifndef TOOLS_DIAGNOSE_EX_H
47 #include <tools/diagnose_ex.h>
48 #endif
49 #ifndef _COMPHELPER_SEQUENCE_HXX_
50 #include <comphelper/sequence.hxx>
51 #endif
52 #ifndef _COMPHELPER_ENUMHELPER_HXX_
53 #include <comphelper/enumhelper.hxx>
54 #endif
55 #ifndef _COMPHELPER_EXTRACT_HXX_
56 #include <comphelper/extract.hxx>
57 #endif
58 #ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
59 #include <com/sun/star/lang/XComponent.hpp>
60 #endif
61 #ifndef _COM_SUN_STAR_UCB_COMMANDINFO_HPP_
62 #include <com/sun/star/ucb/CommandInfo.hpp>
63 #endif
64 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
65 #include <com/sun/star/beans/XPropertySet.hpp>
66 #endif
67 #ifndef _COM_SUN_STAR_SDB_ERRORCONDITION_HPP_
68 #include <com/sun/star/sdb/ErrorCondition.hpp>
69 #endif
70 #ifndef _COMPHELPER_TYPES_HXX_
71 #include <comphelper/types.hxx>
72 #endif
73 #ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX
74 #include <ucbhelper/contentidentifier.hxx>
75 #endif
76 #include <functional>
77 
78 
79 using namespace ::com::sun::star::uno;
80 using namespace ::com::sun::star::lang;
81 using namespace ::com::sun::star::util;
82 using namespace ::com::sun::star::beans;
83 using namespace ::com::sun::star::container;
84 using namespace ::com::sun::star::sdbcx;
85 using namespace ::com::sun::star::sdb;
86 using namespace ::osl;
87 using namespace ::comphelper;
88 using namespace ::cppu;
89 using namespace ::com::sun::star::ucb;
90 
91 //........................................................................
92 namespace dbaccess
93 {
94 //........................................................................
95 
96 //==========================================================================
97 //= ODefinitionContainer_Impl
98 //==========================================================================
99 //--------------------------------------------------------------------------
erase(TContentPtr _pDefinition)100 void ODefinitionContainer_Impl::erase( TContentPtr _pDefinition )
101 {
102     NamedDefinitions::iterator aPos = find( _pDefinition );
103     if ( aPos != end() )
104         m_aDefinitions.erase( aPos );
105 }
106 
107 //--------------------------------------------------------------------------
find(TContentPtr _pDefinition) const108 ODefinitionContainer_Impl::const_iterator ODefinitionContainer_Impl::find( TContentPtr _pDefinition ) const
109 {
110     return ::std::find_if(
111         m_aDefinitions.begin(),
112         m_aDefinitions.end(),
113         ::std::compose1(
114             ::std::bind( ::std::equal_to< TContentPtr >(), ::std::placeholders::_1, _pDefinition ),
115             ::std::select2nd< NamedDefinitions::value_type >()
116         )
117     );
118 }
119 
120 //--------------------------------------------------------------------------
find(TContentPtr _pDefinition)121 ODefinitionContainer_Impl::iterator ODefinitionContainer_Impl::find( TContentPtr _pDefinition )
122 {
123     return ::std::find_if(
124         m_aDefinitions.begin(),
125         m_aDefinitions.end(),
126         ::std::compose1(
127             ::std::bind( ::std::equal_to< TContentPtr >(), ::std::placeholders::_1, _pDefinition ),
128             ::std::select2nd< NamedDefinitions::value_type >()
129         )
130     );
131 }
132 
133 //==========================================================================
134 //= ODefinitionContainer
135 //==========================================================================
DBG_NAME(ODefinitionContainer)136 DBG_NAME(ODefinitionContainer)
137 //--------------------------------------------------------------------------
138 ODefinitionContainer::ODefinitionContainer(   const Reference< XMultiServiceFactory >& _xORB
139                                             , const Reference< XInterface >&    _xParentContainer
140                                             , const TContentPtr& _pImpl
141                                             , bool _bCheckSlash
142                                             )
143     :OContentHelper(_xORB,_xParentContainer,_pImpl)
144     ,m_aApproveListeners(m_aMutex)
145     ,m_aContainerListeners(m_aMutex)
146     ,m_bInPropertyChange(sal_False)
147     ,m_bCheckSlash(_bCheckSlash)
148 {
149     m_pImpl->m_aProps.bIsDocument = sal_False;
150     m_pImpl->m_aProps.bIsFolder = sal_True;
151 
152     const ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
153     ODefinitionContainer_Impl::const_iterator aEnd = rDefinitions.end();
154     for (   ODefinitionContainer_Impl::const_iterator aDefinition = rDefinitions.begin();
155             aDefinition != aEnd;
156             ++aDefinition
157         )
158         m_aDocuments.push_back(
159             m_aDocumentMap.insert(
160                 Documents::value_type( aDefinition->first, Documents::mapped_type() ) ).first );
161 
162     DBG_CTOR(ODefinitionContainer, NULL);
163 }
164 
165 //--------------------------------------------------------------------------
disposing()166 void SAL_CALL ODefinitionContainer::disposing()
167 {
168     OContentHelper::disposing();
169 
170     MutexGuard aGuard(m_aMutex);
171 
172     // say our listeners goobye
173     EventObject aEvt(*this);
174     m_aApproveListeners.disposeAndClear(aEvt);
175     m_aContainerListeners.disposeAndClear(aEvt);
176 
177     // dispose our elements
178     Documents::iterator aIter = m_aDocumentMap.begin();
179     Documents::iterator aEnd = m_aDocumentMap.end();
180 
181     for (; aIter != aEnd; ++aIter)
182     {
183         Reference<XContent> xProp = aIter->second;
184         if ( xProp.is() )
185         {
186             removeObjectListener(xProp);
187             ::comphelper::disposeComponent(xProp);
188         }
189     }
190 
191     // remove our elements
192     m_aDocuments.clear();
193     //  !!! do this before clearing the map which the vector elements refer to !!!
194     m_aDocumentMap.clear();
195 }
196 
197 //--------------------------------------------------------------------------
~ODefinitionContainer()198 ODefinitionContainer::~ODefinitionContainer()
199 {
200     DBG_DTOR(ODefinitionContainer, NULL);
201 }
202 
203 IMPLEMENT_FORWARD_XINTERFACE2( ODefinitionContainer,OContentHelper,ODefinitionContainer_Base)
204 IMPLEMENT_TYPEPROVIDER2(ODefinitionContainer,OContentHelper,ODefinitionContainer_Base);
205 // XServiceInfo
206 //--------------------------------------------------------------------------
getImplementationName()207 ::rtl::OUString SAL_CALL ODefinitionContainer::getImplementationName(  )
208 {
209     return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.ODefinitionContainer"));
210 }
211 //--------------------------------------------------------------------------
getSupportedServiceNames()212 Sequence< ::rtl::OUString > SAL_CALL ODefinitionContainer::getSupportedServiceNames(  )
213 {
214     Sequence< ::rtl::OUString > aReturn(2);
215     aReturn.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.DefinitionContainer"));
216     aReturn.getArray()[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.Content"));
217     return aReturn;
218 }
219 
220 // XNameContainer
221 //--------------------------------------------------------------------------
insertByName(const::rtl::OUString & _rName,const Any & aElement)222 void SAL_CALL ODefinitionContainer::insertByName( const ::rtl::OUString& _rName, const Any& aElement )
223 {
224     ResettableMutexGuard aGuard(m_aMutex);
225 
226     // approve the new object
227     Reference< XContent > xNewElement(aElement,UNO_QUERY);
228     approveNewObject( _rName, xNewElement );  // will throw if necessary
229 
230     notifyByName( aGuard, _rName, xNewElement, NULL, E_INSERTED, ApproveListeners );
231     implAppend( _rName, xNewElement );
232     notifyByName( aGuard, _rName, xNewElement, NULL, E_INSERTED, ContainerListemers );
233 }
234 
235 //--------------------------------------------------------------------------
removeByName(const::rtl::OUString & _rName)236 void SAL_CALL ODefinitionContainer::removeByName( const ::rtl::OUString& _rName )
237 {
238     ResettableMutexGuard aGuard(m_aMutex);
239 
240     // check the arguments
241     if (!_rName.getLength())
242         throw IllegalArgumentException();
243 
244     if (!checkExistence(_rName))
245         throw NoSuchElementException(_rName,*this);
246 
247     // the old element (for the notifications)
248     Reference< XContent > xOldElement = implGetByName( _rName, impl_haveAnyListeners_nothrow() );
249 
250     // do the removal
251     notifyByName( aGuard, _rName, NULL, xOldElement, E_REMOVED, ApproveListeners );
252     implRemove( _rName );
253     notifyByName( aGuard, _rName, NULL, xOldElement, E_REMOVED, ContainerListemers );
254 
255     removeObjectListener( xOldElement );
256     disposeComponent(xOldElement);
257 }
258 
259 // XNameReplace
260 //--------------------------------------------------------------------------
replaceByName(const::rtl::OUString & _rName,const Any & aElement)261 void SAL_CALL ODefinitionContainer::replaceByName( const ::rtl::OUString& _rName, const Any& aElement )
262 {
263     ResettableMutexGuard aGuard(m_aMutex);
264 
265     // let derived classes approve the new object
266     Reference< XContent > xNewElement(aElement,UNO_QUERY);
267     approveNewObject( _rName, xNewElement );    // will throw if necessary
268 
269     // the old element (for the notifications)
270     Reference< XContent > xOldElement = implGetByName( _rName, impl_haveAnyListeners_nothrow() );
271 
272     notifyByName( aGuard, _rName, xNewElement, xOldElement, E_REPLACED, ApproveListeners );
273     implReplace( _rName, xNewElement );
274     notifyByName( aGuard, _rName, xNewElement, xOldElement, E_REPLACED, ContainerListemers );
275 
276     // and dispose it
277     disposeComponent(xOldElement);
278 }
279 
280 // -----------------------------------------------------------------------------
281 namespace
282 {
283     typedef Reference< XVeto > ( SAL_CALL XContainerApproveListener::*ContainerApprovalMethod )( const ContainerEvent& );
284 
285     struct RaiseExceptionFromVeto
286     {
287     private:
288         ContainerApprovalMethod m_pMethod;
289         const ContainerEvent&   m_rEvent;
290 
291     public:
RaiseExceptionFromVetodbaccess::__anon634118fd0111::RaiseExceptionFromVeto292         RaiseExceptionFromVeto( ContainerApprovalMethod _pMethod, const ContainerEvent& _rEvent )
293             :m_pMethod( _pMethod )
294             ,m_rEvent( _rEvent )
295         {
296         }
297 
operator ()dbaccess::__anon634118fd0111::RaiseExceptionFromVeto298         void operator()( const Reference< XContainerApproveListener >& _Listener ) const
299         {
300             Reference< XVeto > xVeto = (_Listener.get()->*m_pMethod)( m_rEvent );
301             if ( !xVeto.is() )
302                 return;
303 
304             Any eVetoDetails = xVeto->getDetails();
305 
306             IllegalArgumentException aIllegalArgumentError;
307             if ( eVetoDetails >>= aIllegalArgumentError )
308                 throw aIllegalArgumentError;
309 
310             WrappedTargetException aWrappedError;
311             if ( eVetoDetails >>= aWrappedError )
312                 throw aWrappedError;
313 
314             throw WrappedTargetException( xVeto->getReason(), _Listener.get(), eVetoDetails );
315         }
316     };
317 }
318 
319 // -----------------------------------------------------------------------------
notifyByName(ResettableMutexGuard & _rGuard,const::rtl::OUString & _rName,const Reference<XContent> & _xNewElement,const Reference<XContent> & _xOldElement,ContainerOperation _eOperation,ListenerType _eType)320 void ODefinitionContainer::notifyByName( ResettableMutexGuard& _rGuard, const ::rtl::OUString& _rName,
321         const Reference< XContent >& _xNewElement, const Reference< XContent >& _xOldElement,
322         ContainerOperation _eOperation, ListenerType _eType )
323 {
324     bool bApprove = ( _eType == ApproveListeners );
325 
326     ::cppu::OInterfaceContainerHelper& rContainer( bApprove ? m_aApproveListeners : m_aContainerListeners );
327     if ( !rContainer.getLength() )
328         return;
329 
330     ContainerEvent aEvent( *this, makeAny( _rName ), makeAny( _xNewElement ), makeAny( _xOldElement ) );
331 
332     _rGuard.clear();
333     switch ( _eOperation )
334     {
335         case E_INSERTED:
336             if ( bApprove )
337                 rContainer.forEach< XContainerApproveListener, RaiseExceptionFromVeto >(
338                     RaiseExceptionFromVeto( &XContainerApproveListener::approveInsertElement, aEvent ) );
339             else
340                 rContainer.notifyEach( &XContainerListener::elementInserted, aEvent );
341             break;
342         case E_REPLACED:
343             if ( bApprove )
344                 rContainer.forEach< XContainerApproveListener, RaiseExceptionFromVeto >(
345                     RaiseExceptionFromVeto( &XContainerApproveListener::approveReplaceElement, aEvent ) );
346             else
347                 rContainer.notifyEach( &XContainerListener::elementReplaced, aEvent );
348             break;
349         case E_REMOVED:
350             if ( bApprove )
351                 rContainer.forEach< XContainerApproveListener, RaiseExceptionFromVeto >(
352                     RaiseExceptionFromVeto( &XContainerApproveListener::approveRemoveElement, aEvent ) );
353             else
354                 rContainer.notifyEach( &XContainerListener::elementRemoved, aEvent );
355             break;
356     }
357 
358     if ( bApprove )
359         _rGuard.reset();
360 }
361 
362 //--------------------------------------------------------------------------
addContainerListener(const Reference<XContainerListener> & _rxListener)363 void SAL_CALL ODefinitionContainer::addContainerListener( const Reference< XContainerListener >& _rxListener )
364 {
365     if (_rxListener.is())
366         m_aContainerListeners.addInterface(_rxListener);
367 }
368 
369 //--------------------------------------------------------------------------
removeContainerListener(const Reference<XContainerListener> & _rxListener)370 void SAL_CALL ODefinitionContainer::removeContainerListener( const Reference< XContainerListener >& _rxListener )
371 {
372     if (_rxListener.is())
373         m_aContainerListeners.removeInterface(_rxListener);
374 }
375 
376 //--------------------------------------------------------------------------
addContainerApproveListener(const Reference<XContainerApproveListener> & _Listener)377 void SAL_CALL ODefinitionContainer::addContainerApproveListener( const Reference< XContainerApproveListener >& _Listener )
378 {
379     if ( _Listener.is() )
380         m_aApproveListeners.addInterface( _Listener );
381 }
382 
383 //--------------------------------------------------------------------------
removeContainerApproveListener(const Reference<XContainerApproveListener> & _Listener)384 void SAL_CALL ODefinitionContainer::removeContainerApproveListener( const Reference< XContainerApproveListener >& _Listener )
385 {
386     if ( _Listener.is() )
387         m_aApproveListeners.removeInterface( _Listener );
388 }
389 
390 
391 // XElementAccess
392 //--------------------------------------------------------------------------
getElementType()393 Type SAL_CALL ODefinitionContainer::getElementType( )
394 {
395     return ::getCppuType( static_cast< Reference< XContent >* >(NULL) );
396 }
397 
398 //--------------------------------------------------------------------------
hasElements()399 sal_Bool SAL_CALL ODefinitionContainer::hasElements( )
400 {
401     MutexGuard aGuard(m_aMutex);
402     return !m_aDocuments.empty();
403 }
404 
405 // XEnumerationAccess
406 //--------------------------------------------------------------------------
createEnumeration()407 Reference< XEnumeration > SAL_CALL ODefinitionContainer::createEnumeration(  )
408 {
409     MutexGuard aGuard(m_aMutex);
410     return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
411 }
412 
413 //--------------------------------------------------------------------------
414 // XIndexAccess
getCount()415 sal_Int32 SAL_CALL ODefinitionContainer::getCount(  )
416 {
417     MutexGuard aGuard(m_aMutex);
418     return m_aDocuments.size();
419 }
420 
421 //--------------------------------------------------------------------------
getByIndex(sal_Int32 _nIndex)422 Any SAL_CALL ODefinitionContainer::getByIndex( sal_Int32 _nIndex )
423 {
424     MutexGuard aGuard(m_aMutex);
425 
426     if ((_nIndex < 0) || (_nIndex >= (sal_Int32)m_aDocuments.size()))
427         throw IndexOutOfBoundsException();
428 
429     Documents::iterator aPos = m_aDocuments[_nIndex];
430     Reference<XContent> xProp = aPos->second;
431     if (!xProp.is())
432     {   // that's the first access to the object
433         // -> create it
434         xProp = createObject(aPos->first);
435         aPos->second = Documents::mapped_type();
436         // and update the name-access map
437     }
438 
439     return makeAny(xProp);
440 }
441 
442 //--------------------------------------------------------------------------
getByName(const::rtl::OUString & _rName)443 Any SAL_CALL ODefinitionContainer::getByName( const ::rtl::OUString& _rName )
444 {
445     MutexGuard aGuard(m_aMutex);
446 
447     return makeAny( implGetByName( _rName, sal_True ) );
448 }
449 
450 //--------------------------------------------------------------------------
implGetByName(const::rtl::OUString & _rName,sal_Bool _bReadIfNeccessary)451 Reference< XContent > ODefinitionContainer::implGetByName(const ::rtl::OUString& _rName, sal_Bool _bReadIfNeccessary)
452 {
453     Documents::iterator aMapPos = m_aDocumentMap.find(_rName);
454     if (aMapPos == m_aDocumentMap.end())
455         throw NoSuchElementException(_rName,*this);
456 
457     Reference< XContent > xProp = aMapPos->second;
458 
459     if (_bReadIfNeccessary && !xProp.is())
460     {   // the object has never been accessed before, so we have to read it now
461         // (that's the expensive part)
462 
463         // create the object and insert it into the map
464         xProp = createObject(_rName);
465         aMapPos->second = xProp;
466         addObjectListener(xProp);
467     }
468 
469     return xProp;
470 }
471 
472 //--------------------------------------------------------------------------
getElementNames()473 Sequence< ::rtl::OUString > SAL_CALL ODefinitionContainer::getElementNames(  )
474 {
475     MutexGuard aGuard(m_aMutex);
476 
477     Sequence< ::rtl::OUString > aNames(m_aDocumentMap.size());
478     ::rtl::OUString* pNames = aNames.getArray();
479     Documents::iterator aEnd = m_aDocumentMap.end();
480     for (   Documents::iterator aNameIter = m_aDocumentMap.begin();
481             aNameIter != aEnd;
482             ++pNames, ++aNameIter
483         )
484     {
485         *pNames = aNameIter->first;
486     }
487 
488     return aNames;
489 }
490 
491 //--------------------------------------------------------------------------
hasByName(const::rtl::OUString & _rName)492 sal_Bool SAL_CALL ODefinitionContainer::hasByName( const ::rtl::OUString& _rName )
493 {
494     MutexGuard aGuard(m_aMutex);
495 
496     return checkExistence(_rName);
497 }
498 
499 //--------------------------------------------------------------------------
disposing(const EventObject & _rSource)500 void SAL_CALL ODefinitionContainer::disposing( const EventObject& _rSource )
501 {
502     MutexGuard aGuard(m_aMutex);
503     Reference< XContent > xSource(_rSource.Source, UNO_QUERY);
504     // it's one of our documents ....
505     Documents::iterator aIter = m_aDocumentMap.begin();
506     Documents::iterator aEnd = m_aDocumentMap.end();
507     for (;aIter != aEnd;++aIter )
508     {
509         if ( xSource == aIter->second.get() )
510         {
511             removeObjectListener(xSource);
512             // and clear our document map/vector, so the object will be recreated on next access
513             aIter->second = Documents::mapped_type();
514         }
515     }
516 }
517 
518 //--------------------------------------------------------------------------
implRemove(const::rtl::OUString & _rName)519 void ODefinitionContainer::implRemove(const ::rtl::OUString& _rName)
520 {
521     // from the object maps
522     Documents::iterator aFind = m_aDocumentMap.find(_rName);
523     if ( aFind != m_aDocumentMap.end() )
524     {
525         m_aDocuments.erase( ::std::find(m_aDocuments.begin(),m_aDocuments.end(),aFind));
526         m_aDocumentMap.erase(aFind);
527 
528         getDefinitions().erase( _rName );
529 
530         notifyDataSourceModified();
531     }
532 }
533 
534 //--------------------------------------------------------------------------
535 namespace
536 {
lcl_ensureName(const Reference<XContent> & _rxContent,const::rtl::OUString & _rName)537     bool    lcl_ensureName( const Reference< XContent >& _rxContent, const ::rtl::OUString& _rName )
538     {
539         if ( !_rxContent.is() )
540             return true;
541 
542         // ..........................................................
543         // obtain the current name. If it's the same as the new one,
544         // don't do anything
545         try
546         {
547             Reference< XPropertySet > xProps( _rxContent, UNO_QUERY );
548             if ( xProps.is() )
549             {
550                 ::rtl::OUString sCurrentName;
551                 OSL_VERIFY( xProps->getPropertyValue( PROPERTY_NAME ) >>= sCurrentName );
552                 if ( sCurrentName.equals( _rName ) )
553                     return true;
554             }
555         }
556         catch( const Exception& )
557         {
558             OSL_ENSURE( sal_False, "lcl_ensureName: caught an exception while obtaining the current name!" );
559         }
560 
561         // ..........................................................
562         // set the new name
563         Reference< XRename > xRename( _rxContent, UNO_QUERY );
564         OSL_ENSURE( xRename.is(), "lcl_ensureName: invalid content (not renameable)!" );
565         if ( !xRename.is() )
566             return false;
567         try
568         {
569             xRename->rename( _rName );
570             return true;
571         }
572         catch( const Exception& )
573         {
574             OSL_ENSURE( sal_False, "lcl_ensureName: caught an exception!" );
575         }
576         return false;
577     }
578 }
579 //--------------------------------------------------------------------------
implAppend(const::rtl::OUString & _rName,const Reference<XContent> & _rxNewObject)580 void ODefinitionContainer::implAppend(const ::rtl::OUString& _rName, const Reference< XContent >& _rxNewObject)
581 {
582     MutexGuard aGuard(m_aMutex);
583     try
584     {
585         Reference<XChild> xChild(_rxNewObject,UNO_QUERY);
586         if ( xChild.is() )
587             xChild->setParent(static_cast<OWeakObject*>(this));
588 
589         ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
590         ODefinitionContainer_Impl::const_iterator aFind = rDefinitions.find( _rName );
591         if ( aFind == rDefinitions.end() )
592         {
593             // ensure that the new object thas the proper name.
594             // Somebody could create an object with name "foo", and insert it as "bar"
595             // into a container. In this case, we need to ensure that the object name
596             // is also "bar"
597             // #i44786# / 2005-03-11 / frank.schoenheit@sun.com
598             lcl_ensureName( _rxNewObject, _rName );
599 
600             ::rtl::Reference< OContentHelper > pContent = OContentHelper::getImplementation( _rxNewObject );
601             if ( pContent.is() )
602             {
603                 TContentPtr pImpl = pContent->getImpl();
604                 rDefinitions.erase( pImpl );
605                 pImpl->m_aProps.aTitle = _rName;
606                 rDefinitions.insert( _rName, pImpl );
607             }
608         }
609 
610 
611         m_aDocuments.push_back(m_aDocumentMap.insert(Documents::value_type(_rName,_rxNewObject)).first);
612         notifyDataSourceModified();
613         // now update our structures
614         if ( _rxNewObject.is() )
615             addObjectListener(_rxNewObject);
616     }
617     catch(Exception&)
618     {
619         DBG_ERROR("ODefinitionContainer::implAppend: caught something !");
620     }
621 }
622 
623 //--------------------------------------------------------------------------
implReplace(const::rtl::OUString & _rName,const Reference<XContent> & _rxNewObject)624 void ODefinitionContainer::implReplace(const ::rtl::OUString& _rName, const Reference< XContent >& _rxNewObject)
625 {
626     DBG_ASSERT(checkExistence(_rName), "ODefinitionContainer::implReplace : invalid name !");
627 
628     Documents::iterator aFind = m_aDocumentMap.find(_rName);
629     removeObjectListener(aFind->second);
630     aFind->second = _rxNewObject;
631     addObjectListener(aFind->second);
632 }
633 
634 // -----------------------------------------------------------------------------
approveNewObject(const::rtl::OUString & _sName,const Reference<XContent> & _rxObject) const635 void ODefinitionContainer::approveNewObject(const ::rtl::OUString& _sName,const Reference< XContent >& _rxObject) const
636 {
637     // check the arguments
638     if ( !_sName.getLength() )
639         throw IllegalArgumentException(
640             DBA_RES( RID_STR_NAME_MUST_NOT_BE_EMPTY ),
641             *this,
642             0 );
643 
644     if ( m_bCheckSlash && _sName.indexOf( '/' ) != -1 )
645         throw IllegalArgumentException(
646             m_aErrorHelper.getErrorMessage( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES ),
647             *this,
648             0 );
649 
650     if ( !_rxObject.is() )
651         throw IllegalArgumentException(
652             DBA_RES( RID_STR_NO_NULL_OBJECTS_IN_CONTAINER ),
653             *this,
654             0 );
655 
656     const ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
657     if ( rDefinitions.find( _sName ) != rDefinitions.end() )
658         throw ElementExistException(
659             DBA_RES( RID_STR_NAME_ALREADY_USED ),
660             *this );
661 
662     ::rtl::Reference< OContentHelper > pContent( OContentHelper::getImplementation( _rxObject ) );
663     if ( !pContent.is() )
664         throw IllegalArgumentException(
665             DBA_RES( RID_STR_OBJECT_CONTAINER_MISMATCH ),
666             *this,
667             1 );
668 
669     if ( rDefinitions.find( pContent->getImpl() ) != rDefinitions.end() )
670         throw ElementExistException(
671             DBA_RES( RID_STR_OBJECT_ALREADY_CONTAINED ),
672             *this );
673 }
674 
675 // -----------------------------------------------------------------------------
676 // XPropertyChangeListener
propertyChange(const PropertyChangeEvent & evt)677 void SAL_CALL ODefinitionContainer::propertyChange( const PropertyChangeEvent& evt )
678 {
679     ClearableMutexGuard aGuard(m_aMutex);
680     if(evt.PropertyName == (rtl::OUString) PROPERTY_NAME || evt.PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ))
681     {
682         m_bInPropertyChange = sal_True;
683         try
684         {
685             ::rtl::OUString sNewName,sOldName;
686             evt.OldValue >>= sOldName;
687             evt.NewValue >>= sNewName;
688             Reference<XContent> xContent( evt.Source, UNO_QUERY );
689             removeObjectListener( xContent );
690             implRemove( sOldName );
691             implAppend( sNewName, xContent );
692         }
693         catch(const Exception&)
694         {
695             DBG_UNHANDLED_EXCEPTION();
696             throw RuntimeException();
697         }
698         m_bInPropertyChange = sal_False;
699     }
700 }
701 // -----------------------------------------------------------------------------
702 // XVetoableChangeListener
vetoableChange(const PropertyChangeEvent & aEvent)703 void SAL_CALL ODefinitionContainer::vetoableChange( const PropertyChangeEvent& aEvent )
704 {
705     MutexGuard aGuard(m_aMutex);
706 
707     if(aEvent.PropertyName == (rtl::OUString) PROPERTY_NAME || aEvent.PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
708     {
709         ::rtl::OUString sNewName;
710         aEvent.NewValue >>= sNewName;
711         if(hasByName(sNewName))
712             throw PropertyVetoException();
713     }
714 }
715 // -----------------------------------------------------------------------------
addObjectListener(const Reference<XContent> & _xNewObject)716 void ODefinitionContainer::addObjectListener(const Reference< XContent >& _xNewObject)
717 {
718     OSL_ENSURE(_xNewObject.is(),"ODefinitionContainer::addObjectListener: Object is null!");
719     Reference<XPropertySet> xProp(_xNewObject,UNO_QUERY);
720     if ( xProp.is() )
721     {
722         xProp->addPropertyChangeListener(PROPERTY_NAME, this);
723         xProp->addVetoableChangeListener(PROPERTY_NAME, this);
724     }
725 }
726 // -----------------------------------------------------------------------------
removeObjectListener(const Reference<XContent> & _xNewObject)727 void ODefinitionContainer::removeObjectListener(const Reference< XContent >& _xNewObject)
728 {
729     Reference<XPropertySet> xProp(_xNewObject,UNO_QUERY);
730     if ( xProp.is() )
731     {
732         xProp->removePropertyChangeListener(PROPERTY_NAME, this);
733         xProp->removeVetoableChangeListener(PROPERTY_NAME, this);
734     }
735 }
736 // -----------------------------------------------------------------------------
checkExistence(const::rtl::OUString & _rName)737 sal_Bool ODefinitionContainer::checkExistence(const ::rtl::OUString& _rName)
738 {
739     return m_aDocumentMap.find(_rName) != m_aDocumentMap.end();
740 }
741 
742 //........................................................................
743 }
744 // namespace dbaccess
745 //........................................................................
746