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