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