bump product version to 4.1.6.2
[LibreOffice.git] / ucbhelper / source / provider / contenthelper.cxx
blob2f1fde05a1f108be54f091bceb3cb2d2afbad704
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 /**************************************************************************
21 TODO
22 **************************************************************************
24 *************************************************************************/
26 #include <boost/unordered_map.hpp>
27 #include <com/sun/star/ucb/ContentAction.hpp>
28 #include <com/sun/star/ucb/CommandInfoChange.hpp>
29 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
30 #include <com/sun/star/beans/PropertyAttribute.hpp>
31 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
32 #include <cppuhelper/interfacecontainer.hxx>
34 #include "osl/diagnose.h"
35 #include "osl/mutex.hxx"
36 #include "rtl/ref.hxx"
37 #include <ucbhelper/contentidentifier.hxx>
38 #include <ucbhelper/contenthelper.hxx>
39 #include <ucbhelper/providerhelper.hxx>
40 #include <ucbhelper/contentinfo.hxx>
42 using namespace com::sun::star;
44 namespace ucbhelper_impl
47 //=========================================================================
49 // class PropertyEventSequence.
51 //=========================================================================
53 class PropertyEventSequence
55 uno::Sequence< beans::PropertyChangeEvent > m_aSeq;
56 sal_uInt32 m_nPos;
58 public:
59 PropertyEventSequence( sal_uInt32 nSize )
60 : m_aSeq( nSize ), m_nPos( 0 ) {};
62 void append( const beans::PropertyChangeEvent& rEvt )
63 { m_aSeq.getArray()[ m_nPos ] = rEvt; ++m_nPos; }
65 const uno::Sequence< beans::PropertyChangeEvent >& getEvents()
66 { m_aSeq.realloc( m_nPos ); return m_aSeq; }
69 //=========================================================================
71 // PropertiesEventListenerMap.
73 //=========================================================================
75 typedef void* XPropertiesChangeListenerPtr; // -> Compiler problems!
77 struct equalPtr
79 bool operator()( const XPropertiesChangeListenerPtr& rp1,
80 const XPropertiesChangeListenerPtr& rp2 ) const
82 return ( rp1 == rp2 );
86 struct hashPtr
88 size_t operator()( const XPropertiesChangeListenerPtr& rp ) const
90 return (size_t)rp;
94 typedef boost::unordered_map
96 XPropertiesChangeListenerPtr,
97 PropertyEventSequence*,
98 hashPtr,
99 equalPtr
101 PropertiesEventListenerMap;
103 //=========================================================================
105 // PropertyChangeListenerContainer.
107 //=========================================================================
109 struct equalStr
111 bool operator()( const OUString& s1, const OUString& s2 ) const
113 return !!( s1 == s2 );
117 struct hashStr
119 size_t operator()( const OUString& rName ) const
121 return rName.hashCode();
125 typedef cppu::OMultiTypeInterfaceContainerHelperVar
127 OUString,
128 hashStr,
129 equalStr
130 > PropertyChangeListeners;
132 //=========================================================================
134 // struct ContentImplHelper_Impl
136 //=========================================================================
138 struct ContentImplHelper_Impl
140 rtl::Reference< ::ucbhelper::PropertySetInfo > m_xPropSetInfo;
141 rtl::Reference< ::ucbhelper::CommandProcessorInfo > m_xCommandsInfo;
142 cppu::OInterfaceContainerHelper* m_pDisposeEventListeners;
143 cppu::OInterfaceContainerHelper* m_pContentEventListeners;
144 cppu::OInterfaceContainerHelper* m_pPropSetChangeListeners;
145 cppu::OInterfaceContainerHelper* m_pCommandChangeListeners;
146 PropertyChangeListeners* m_pPropertyChangeListeners;
148 ContentImplHelper_Impl()
149 : m_pDisposeEventListeners( 0 ),
150 m_pContentEventListeners( 0 ),
151 m_pPropSetChangeListeners( 0 ),
152 m_pCommandChangeListeners( 0 ),
153 m_pPropertyChangeListeners( 0 ) {}
155 ~ContentImplHelper_Impl()
157 delete m_pDisposeEventListeners;
158 delete m_pContentEventListeners;
159 delete m_pPropSetChangeListeners;
160 delete m_pCommandChangeListeners;
161 delete m_pPropertyChangeListeners;
165 } // namespace ucbhelper_impl
167 using namespace ucbhelper_impl;
169 //=========================================================================
170 //=========================================================================
172 // ContentImplHelper Implementation.
174 //=========================================================================
175 //=========================================================================
177 namespace ucbhelper {
179 ContentImplHelper::ContentImplHelper(
180 const uno::Reference< uno::XComponentContext >& rxContext,
181 const rtl::Reference< ContentProviderImplHelper >& rxProvider,
182 const uno::Reference<
183 com::sun::star::ucb::XContentIdentifier >& Identifier )
184 : m_pImpl( new ContentImplHelper_Impl ),
185 m_xContext( rxContext ),
186 m_xIdentifier( Identifier ),
187 m_xProvider( rxProvider ),
188 m_nCommandId( 0 )
192 //=========================================================================
193 // virtual
194 ContentImplHelper::~ContentImplHelper()
196 delete m_pImpl;
199 //=========================================================================
201 // XInterface methods.
203 //=========================================================================
205 void SAL_CALL ContentImplHelper::acquire()
206 throw()
208 cppu::OWeakObject::acquire();
211 void SAL_CALL ContentImplHelper::release()
212 throw()
214 // #144882# - Call to OWeakObject::release may destroy m_xProvider.
215 // Prevent this.
216 rtl::Reference< ContentProviderImplHelper > xKeepProviderAlive(
217 m_xProvider );
220 osl::MutexGuard aGuard( m_xProvider->m_aMutex );
221 OWeakObject::release();
225 uno::Any SAL_CALL ContentImplHelper::queryInterface( const uno::Type & rType )
226 throw( uno::RuntimeException )
228 com::sun::star::uno::Any aRet = cppu::queryInterface( rType,
229 static_cast< lang::XTypeProvider * >(this),
230 static_cast< lang::XServiceInfo * >(this),
231 static_cast< lang::XComponent * >(this),
232 static_cast< com::sun::star::ucb::XContent * >(this),
233 static_cast< com::sun::star::ucb::XCommandProcessor * >(this),
234 static_cast< beans::XPropertiesChangeNotifier * >(this),
235 static_cast< com::sun::star::ucb::XCommandInfoChangeNotifier * >(this),
236 static_cast< beans::XPropertyContainer * >(this),
237 static_cast< beans::XPropertySetInfoChangeNotifier * >(this),
238 static_cast< container::XChild * >(this));
239 return aRet.hasValue() ? aRet : cppu::OWeakObject::queryInterface( rType );
242 //=========================================================================
244 // XTypeProvider methods.
246 //=========================================================================
248 XTYPEPROVIDER_IMPL_10( ContentImplHelper,
249 lang::XTypeProvider,
250 lang::XServiceInfo,
251 lang::XComponent,
252 com::sun::star::ucb::XContent,
253 com::sun::star::ucb::XCommandProcessor,
254 beans::XPropertiesChangeNotifier,
255 com::sun::star::ucb::XCommandInfoChangeNotifier,
256 beans::XPropertyContainer,
257 beans::XPropertySetInfoChangeNotifier,
258 container::XChild );
260 //=========================================================================
262 // XServiceInfo methods.
264 //=========================================================================
266 // virtual
267 sal_Bool SAL_CALL ContentImplHelper::supportsService(
268 const OUString& ServiceName )
269 throw( uno::RuntimeException )
271 uno::Sequence< OUString > aSNL = getSupportedServiceNames();
272 const OUString* pArray = aSNL.getConstArray();
273 for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
275 if ( pArray[ i ] == ServiceName )
276 return sal_True;
279 return sal_False;
282 //=========================================================================
284 // XComponent methods.
286 //=========================================================================
288 // virtual
289 void SAL_CALL ContentImplHelper::dispose()
290 throw( uno::RuntimeException )
292 osl::MutexGuard aGuard( m_aMutex );
294 if ( m_pImpl->m_pDisposeEventListeners &&
295 m_pImpl->m_pDisposeEventListeners->getLength() )
297 lang::EventObject aEvt;
298 aEvt.Source = static_cast< lang::XComponent * >( this );
299 m_pImpl->m_pDisposeEventListeners->disposeAndClear( aEvt );
302 if ( m_pImpl->m_pContentEventListeners &&
303 m_pImpl->m_pContentEventListeners->getLength() )
305 lang::EventObject aEvt;
306 aEvt.Source = static_cast< com::sun::star::ucb::XContent * >( this );
307 m_pImpl->m_pContentEventListeners->disposeAndClear( aEvt );
310 if ( m_pImpl->m_pPropSetChangeListeners &&
311 m_pImpl->m_pPropSetChangeListeners->getLength() )
313 lang::EventObject aEvt;
314 aEvt.Source
315 = static_cast< beans::XPropertySetInfoChangeNotifier * >( this );
316 m_pImpl->m_pPropSetChangeListeners->disposeAndClear( aEvt );
319 if ( m_pImpl->m_pCommandChangeListeners &&
320 m_pImpl->m_pCommandChangeListeners->getLength() )
322 lang::EventObject aEvt;
323 aEvt.Source = static_cast< com::sun::star::ucb::XCommandInfoChangeNotifier * >( this );
324 m_pImpl->m_pCommandChangeListeners->disposeAndClear( aEvt );
327 if ( m_pImpl->m_pPropertyChangeListeners )
329 lang::EventObject aEvt;
330 aEvt.Source
331 = static_cast< beans::XPropertiesChangeNotifier * >( this );
332 m_pImpl->m_pPropertyChangeListeners->disposeAndClear( aEvt );
336 //=========================================================================
337 // virtual
338 void SAL_CALL ContentImplHelper::addEventListener(
339 const uno::Reference< lang::XEventListener >& Listener )
340 throw( uno::RuntimeException )
342 osl::MutexGuard aGuard( m_aMutex );
344 if ( !m_pImpl->m_pDisposeEventListeners )
345 m_pImpl->m_pDisposeEventListeners
346 = new cppu::OInterfaceContainerHelper( m_aMutex );
348 m_pImpl->m_pDisposeEventListeners->addInterface( Listener );
351 //=========================================================================
352 // virtual
353 void SAL_CALL ContentImplHelper::removeEventListener(
354 const uno::Reference< lang::XEventListener >& Listener )
355 throw( uno::RuntimeException )
357 osl::MutexGuard aGuard( m_aMutex );
359 if ( m_pImpl->m_pDisposeEventListeners )
360 m_pImpl->m_pDisposeEventListeners->removeInterface( Listener );
363 //=========================================================================
365 // XContent methods.
367 //=========================================================================
369 // virtual
370 uno::Reference< com::sun::star::ucb::XContentIdentifier > SAL_CALL
371 ContentImplHelper::getIdentifier()
372 throw( uno::RuntimeException )
374 return m_xIdentifier;
377 //=========================================================================
378 // virtual
379 void SAL_CALL ContentImplHelper::addContentEventListener(
380 const uno::Reference< com::sun::star::ucb::XContentEventListener >& Listener )
381 throw( uno::RuntimeException )
383 osl::MutexGuard aGuard( m_aMutex );
385 if ( !m_pImpl->m_pContentEventListeners )
386 m_pImpl->m_pContentEventListeners
387 = new cppu::OInterfaceContainerHelper( m_aMutex );
389 m_pImpl->m_pContentEventListeners->addInterface( Listener );
392 //=========================================================================
393 // virtual
394 void SAL_CALL ContentImplHelper::removeContentEventListener(
395 const uno::Reference< com::sun::star::ucb::XContentEventListener >& Listener )
396 throw( uno::RuntimeException )
398 osl::MutexGuard aGuard( m_aMutex );
400 if ( m_pImpl->m_pContentEventListeners )
401 m_pImpl->m_pContentEventListeners->removeInterface( Listener );
404 //=========================================================================
406 // XCommandProcessor methods.
408 //=========================================================================
410 // virtual
411 sal_Int32 SAL_CALL ContentImplHelper::createCommandIdentifier()
412 throw( uno::RuntimeException )
414 osl::MutexGuard aGuard( m_aMutex );
416 // Just increase counter on every call to generate an identifier.
417 return ++m_nCommandId;
420 //=========================================================================
422 // XPropertiesChangeNotifier methods.
424 //=========================================================================
426 // virtual
427 void SAL_CALL ContentImplHelper::addPropertiesChangeListener(
428 const uno::Sequence< OUString >& PropertyNames,
429 const uno::Reference< beans::XPropertiesChangeListener >& Listener )
430 throw( uno::RuntimeException )
432 osl::MutexGuard aGuard( m_aMutex );
434 if ( !m_pImpl->m_pPropertyChangeListeners )
435 m_pImpl->m_pPropertyChangeListeners
436 = new PropertyChangeListeners( m_aMutex );
438 sal_Int32 nCount = PropertyNames.getLength();
439 if ( !nCount )
441 // Note: An empty sequence means a listener for "all" properties.
442 m_pImpl->m_pPropertyChangeListeners->addInterface(
443 OUString(), Listener );
445 else
447 const OUString* pSeq = PropertyNames.getConstArray();
449 for ( sal_Int32 n = 0; n < nCount; ++n )
451 const OUString& rName = pSeq[ n ];
452 if ( !rName.isEmpty() )
453 m_pImpl->m_pPropertyChangeListeners->addInterface(
454 rName, Listener );
459 //=========================================================================
460 // virtual
461 void SAL_CALL ContentImplHelper::removePropertiesChangeListener(
462 const uno::Sequence< OUString >& PropertyNames,
463 const uno::Reference< beans::XPropertiesChangeListener >& Listener )
464 throw( uno::RuntimeException )
466 osl::MutexGuard aGuard( m_aMutex );
468 if ( !m_pImpl->m_pPropertyChangeListeners )
469 return;
471 sal_Int32 nCount = PropertyNames.getLength();
472 if ( !nCount )
474 // Note: An empty sequence means a listener for "all" properties.
475 m_pImpl->m_pPropertyChangeListeners->removeInterface(
476 OUString(), Listener );
478 else
480 const OUString* pSeq = PropertyNames.getConstArray();
482 for ( sal_Int32 n = 0; n < nCount; ++n )
484 const OUString& rName = pSeq[ n ];
485 if ( !rName.isEmpty() )
486 m_pImpl->m_pPropertyChangeListeners->removeInterface(
487 rName, Listener );
492 //=========================================================================
494 // XCommandInfoChangeNotifier methods.
496 //=========================================================================
498 // virtual
499 void SAL_CALL ContentImplHelper::addCommandInfoChangeListener(
500 const uno::Reference< com::sun::star::ucb::XCommandInfoChangeListener >& Listener )
501 throw( uno::RuntimeException )
503 osl::MutexGuard aGuard( m_aMutex );
505 if ( !m_pImpl->m_pCommandChangeListeners )
506 m_pImpl->m_pCommandChangeListeners
507 = new cppu::OInterfaceContainerHelper( m_aMutex );
509 m_pImpl->m_pCommandChangeListeners->addInterface( Listener );
512 //=========================================================================
513 // virtual
514 void SAL_CALL ContentImplHelper::removeCommandInfoChangeListener(
515 const uno::Reference< com::sun::star::ucb::XCommandInfoChangeListener >& Listener )
516 throw( uno::RuntimeException )
518 osl::MutexGuard aGuard( m_aMutex );
520 if ( m_pImpl->m_pCommandChangeListeners )
521 m_pImpl->m_pCommandChangeListeners->removeInterface( Listener );
524 //=========================================================================
526 // XPropertyContainer methods.
528 //=========================================================================
530 // virtual
531 void SAL_CALL ContentImplHelper::addProperty(
532 const OUString& Name,
533 sal_Int16 Attributes,
534 const uno::Any& DefaultValue )
535 throw( beans::PropertyExistException,
536 beans::IllegalTypeException,
537 lang::IllegalArgumentException,
538 uno::RuntimeException )
540 osl::MutexGuard aGuard( m_aMutex );
542 //////////////////////////////////////////////////////////////////////
543 // Make sure a property with the requested name does not already
544 // exist in dynamic and static(!) properties.
545 //////////////////////////////////////////////////////////////////////
547 // @@@ Need real command environment here, but where to get it from?
548 // XPropertyContainer interface should be replaced by
549 // XCommandProcessor commands!
550 uno::Reference< com::sun::star::ucb::XCommandEnvironment > xEnv;
552 if ( getPropertySetInfo( xEnv )->hasPropertyByName( Name ) )
554 // Property does already exist.
555 throw beans::PropertyExistException();
558 //////////////////////////////////////////////////////////////////////
559 // Add a new dynamic property.
560 //////////////////////////////////////////////////////////////////////
562 // Open/create persistent property set.
563 uno::Reference< com::sun::star::ucb::XPersistentPropertySet > xSet(
564 getAdditionalPropertySet( sal_True ) );
566 OSL_ENSURE( xSet.is(),
567 "ContentImplHelper::addProperty - No property set!" );
569 if ( xSet.is() )
571 uno::Reference< beans::XPropertyContainer > xContainer(
572 xSet, uno::UNO_QUERY );
574 OSL_ENSURE(
575 xContainer.is(),
576 "ContentImplHelper::addProperty - No property container!" );
578 if ( xContainer.is() )
580 // Property is always removable.
581 Attributes |= beans::PropertyAttribute::REMOVABLE;
585 xContainer->addProperty( Name, Attributes, DefaultValue );
587 catch ( beans::PropertyExistException const & )
589 OSL_FAIL( "ContentImplHelper::addProperty - Exists!" );
590 throw;
592 catch ( beans::IllegalTypeException const & )
594 OSL_FAIL( "ContentImplHelper::addProperty - Wrong Type!" );
595 throw;
597 catch ( lang::IllegalArgumentException const & )
599 OSL_FAIL( "ContentImplHelper::addProperty - Illegal Arg!" );
600 throw;
603 // Success!
605 if ( m_pImpl->m_xPropSetInfo.is() )
607 // Info cached in propertyset info is invalid now!
608 m_pImpl->m_xPropSetInfo->reset();
611 // Notify propertyset info change listeners.
612 if ( m_pImpl->m_pPropSetChangeListeners &&
613 m_pImpl->m_pPropSetChangeListeners->getLength() )
615 beans::PropertySetInfoChangeEvent evt(
616 static_cast< cppu::OWeakObject * >( this ),
617 Name,
618 -1, // No handle available
619 beans::PropertySetInfoChange::PROPERTY_INSERTED );
620 notifyPropertySetInfoChange( evt );
626 //=========================================================================
627 // virtual
628 void SAL_CALL ContentImplHelper::removeProperty( const OUString& Name )
629 throw( beans::UnknownPropertyException,
630 beans::NotRemoveableException,
631 uno::RuntimeException )
633 osl::MutexGuard aGuard( m_aMutex );
637 // @@@ Need real command environment here, but where to get it from?
638 // XPropertyContainer interface should be replaced by
639 // XCommandProcessor commands!
640 uno::Reference< com::sun::star::ucb::XCommandEnvironment > xEnv;
642 beans::Property aProp
643 = getPropertySetInfo( xEnv )->getPropertyByName( Name );
645 if ( !( aProp.Attributes & beans::PropertyAttribute::REMOVABLE ) )
647 // Not removable!
648 throw beans::NotRemoveableException();
651 catch ( beans::UnknownPropertyException const & )
653 OSL_FAIL( "ContentImplHelper::removeProperty - Unknown!" );
654 throw;
657 //////////////////////////////////////////////////////////////////////
658 // Try to remove property from dynamic property set.
659 //////////////////////////////////////////////////////////////////////
661 // Open persistent property set, if exists.
662 uno::Reference< com::sun::star::ucb::XPersistentPropertySet > xSet(
663 getAdditionalPropertySet( sal_False ) );
664 if ( xSet.is() )
666 uno::Reference< beans::XPropertyContainer > xContainer(
667 xSet, uno::UNO_QUERY );
669 OSL_ENSURE(
670 xContainer.is(),
671 "ContentImplHelper::removeProperty - No property container!" );
673 if ( xContainer.is() )
677 xContainer->removeProperty( Name );
679 catch ( beans::UnknownPropertyException const & )
681 OSL_FAIL( "ContentImplHelper::removeProperty - Unknown!" );
682 throw;
684 catch ( beans::NotRemoveableException const & )
686 OSL_FAIL(
687 "ContentImplHelper::removeProperty - Unremovable!" );
688 throw;
691 xContainer = 0;
693 // Success!
695 if ( xSet->getPropertySetInfo()->getProperties().getLength() == 0 )
697 // Remove empty propertyset from registry.
698 uno::Reference< com::sun::star::ucb::XPropertySetRegistry >
699 xReg = xSet->getRegistry();
700 if ( xReg.is() )
702 OUString aKey( xSet->getKey() );
703 xSet = 0;
704 xReg->removePropertySet( aKey );
708 if ( m_pImpl->m_xPropSetInfo.is() )
710 // Info cached in propertyset info is invalid now!
711 m_pImpl->m_xPropSetInfo->reset();
714 // Notify propertyset info change listeners.
715 if ( m_pImpl->m_pPropSetChangeListeners &&
716 m_pImpl->m_pPropSetChangeListeners->getLength() )
718 beans::PropertySetInfoChangeEvent evt(
719 static_cast< cppu::OWeakObject * >( this ),
720 Name,
721 -1, // No handle available
722 beans::PropertySetInfoChange::PROPERTY_REMOVED );
723 notifyPropertySetInfoChange( evt );
729 //=========================================================================
731 // XPropertySetInfoChangeNotifier methods.
733 //=========================================================================
735 // virtual
736 void SAL_CALL ContentImplHelper::addPropertySetInfoChangeListener(
737 const uno::Reference< beans::XPropertySetInfoChangeListener >& Listener )
738 throw( uno::RuntimeException )
740 osl::MutexGuard aGuard( m_aMutex );
742 if ( !m_pImpl->m_pPropSetChangeListeners )
743 m_pImpl->m_pPropSetChangeListeners
744 = new cppu::OInterfaceContainerHelper( m_aMutex );
746 m_pImpl->m_pPropSetChangeListeners->addInterface( Listener );
749 //=========================================================================
750 // virtual
751 void SAL_CALL ContentImplHelper::removePropertySetInfoChangeListener(
752 const uno::Reference< beans::XPropertySetInfoChangeListener >& Listener )
753 throw( uno::RuntimeException )
755 osl::MutexGuard aGuard( m_aMutex );
757 if ( m_pImpl->m_pPropSetChangeListeners )
758 m_pImpl->m_pPropSetChangeListeners->removeInterface( Listener );
761 //=========================================================================
763 // XChild methods.
765 //=========================================================================
767 // virtual
768 uno::Reference< uno::XInterface > SAL_CALL ContentImplHelper::getParent()
769 throw( uno::RuntimeException )
771 uno::Reference< uno::XInterface > xParent;
772 OUString aURL = getParentURL();
774 if ( !aURL.isEmpty() )
776 uno::Reference< com::sun::star::ucb::XContentIdentifier > xId(
777 new ContentIdentifier( aURL ) );
780 xParent.set( m_xProvider->queryContent( xId ) );
782 catch ( com::sun::star::ucb::IllegalIdentifierException const & )
787 return xParent;
790 //=========================================================================
791 // virtual
792 void SAL_CALL ContentImplHelper::setParent(
793 const uno::Reference< uno::XInterface >& )
794 throw( lang::NoSupportException, uno::RuntimeException )
796 throw lang::NoSupportException();
799 //=========================================================================
801 // Non-interface methods
803 //=========================================================================
805 uno::Reference< com::sun::star::ucb::XPersistentPropertySet >
806 ContentImplHelper::getAdditionalPropertySet( sal_Bool bCreate )
808 // Get propertyset from provider.
809 return m_xProvider->getAdditionalPropertySet(
810 m_xIdentifier->getContentIdentifier(), bCreate );
813 //=========================================================================
814 sal_Bool ContentImplHelper::renameAdditionalPropertySet(
815 const OUString& rOldKey,
816 const OUString& rNewKey,
817 sal_Bool bRecursive )
819 return m_xProvider->renameAdditionalPropertySet(
820 rOldKey, rNewKey, bRecursive );
823 //=========================================================================
824 sal_Bool ContentImplHelper::copyAdditionalPropertySet(
825 const OUString& rSourceKey,
826 const OUString& rTargetKey,
827 sal_Bool bRecursive )
829 return m_xProvider->copyAdditionalPropertySet(
830 rSourceKey, rTargetKey, bRecursive );
833 //=========================================================================
834 sal_Bool ContentImplHelper::removeAdditionalPropertySet( sal_Bool bRecursive )
836 return m_xProvider->removeAdditionalPropertySet(
837 m_xIdentifier->getContentIdentifier(), bRecursive );
840 //=========================================================================
841 void ContentImplHelper::notifyPropertiesChange(
842 const uno::Sequence< beans::PropertyChangeEvent >& evt ) const
844 if ( !m_pImpl->m_pPropertyChangeListeners )
845 return;
847 sal_Int32 nCount = evt.getLength();
848 if ( nCount )
850 // First, notify listeners interested in changes of every property.
851 cppu::OInterfaceContainerHelper* pAllPropsContainer
852 = m_pImpl->m_pPropertyChangeListeners->getContainer(
853 OUString() );
854 if ( pAllPropsContainer )
856 cppu::OInterfaceIteratorHelper aIter( *pAllPropsContainer );
857 while ( aIter.hasMoreElements() )
859 // Propagate event.
860 uno::Reference< beans::XPropertiesChangeListener > xListener(
861 aIter.next(), uno::UNO_QUERY );
862 if ( xListener.is() )
863 xListener->propertiesChange( evt );
867 PropertiesEventListenerMap aListeners;
869 const beans::PropertyChangeEvent* pEvents = evt.getConstArray();
871 for ( sal_Int32 n = 0; n < nCount; ++n )
873 const beans::PropertyChangeEvent& rEvent = pEvents[ n ];
874 const OUString& rName = rEvent.PropertyName;
876 cppu::OInterfaceContainerHelper* pPropsContainer
877 = m_pImpl->m_pPropertyChangeListeners->getContainer( rName );
878 if ( pPropsContainer )
880 cppu::OInterfaceIteratorHelper aIter( *pPropsContainer );
881 while ( aIter.hasMoreElements() )
883 PropertyEventSequence* p = NULL;
885 beans::XPropertiesChangeListener* pListener =
886 static_cast< beans::XPropertiesChangeListener * >(
887 aIter.next() );
888 PropertiesEventListenerMap::iterator it =
889 aListeners.find( pListener );
890 if ( it == aListeners.end() )
892 // Not in map - create and insert new entry.
893 p = new PropertyEventSequence( nCount );
894 aListeners[ pListener ] = p;
896 else
897 p = (*it).second;
899 if ( p )
900 p->append( rEvent );
905 // Notify listeners.
906 PropertiesEventListenerMap::iterator it = aListeners.begin();
907 while ( !aListeners.empty() )
909 beans::XPropertiesChangeListener* pListener =
910 static_cast< beans::XPropertiesChangeListener * >( (*it).first );
911 PropertyEventSequence* pSeq = (*it).second;
913 // Remove current element.
914 aListeners.erase( it );
916 // Propagate event.
917 pListener->propertiesChange( pSeq->getEvents() );
919 delete pSeq;
921 it = aListeners.begin();
926 //=========================================================================
927 void ContentImplHelper::notifyPropertySetInfoChange(
928 const beans::PropertySetInfoChangeEvent& evt ) const
930 if ( !m_pImpl->m_pPropSetChangeListeners )
931 return;
933 // Notify event listeners.
934 cppu::OInterfaceIteratorHelper aIter( *m_pImpl->m_pPropSetChangeListeners );
935 while ( aIter.hasMoreElements() )
937 // Propagate event.
938 uno::Reference< beans::XPropertySetInfoChangeListener >
939 xListener( aIter.next(), uno::UNO_QUERY );
940 if ( xListener.is() )
941 xListener->propertySetInfoChange( evt );
945 //=========================================================================
946 void ContentImplHelper::notifyContentEvent(
947 const com::sun::star::ucb::ContentEvent& evt ) const
949 if ( !m_pImpl->m_pContentEventListeners )
950 return;
952 // Notify event listeners.
953 cppu::OInterfaceIteratorHelper aIter( *m_pImpl->m_pContentEventListeners );
954 while ( aIter.hasMoreElements() )
956 // Propagate event.
957 uno::Reference<
958 com::sun::star::ucb::XContentEventListener > xListener(
959 aIter.next(), uno::UNO_QUERY );
960 if ( xListener.is() )
961 xListener->contentEvent( evt );
965 //=========================================================================
966 void ContentImplHelper::inserted()
968 // Content is not yet registered at provider.
969 m_xProvider->registerNewContent( this );
971 // If the parent content is currently not instanciated, there can be
972 // no listeners interested in changes ;-)
974 rtl::Reference< ContentImplHelper > xParent
975 = m_xProvider->queryExistingContent( getParentURL() );
977 if ( xParent.is() )
979 com::sun::star::ucb::ContentEvent aEvt(
980 static_cast< cppu::OWeakObject * >( xParent.get() ), // Source
981 com::sun::star::ucb::ContentAction::INSERTED, // Action
982 this, // Content
983 xParent->getIdentifier() ); // Id
984 xParent->notifyContentEvent( aEvt );
988 //=========================================================================
989 void ContentImplHelper::deleted()
991 uno::Reference< com::sun::star::ucb::XContent > xThis = this;
993 rtl::Reference< ContentImplHelper > xParent
994 = m_xProvider->queryExistingContent( getParentURL() );
996 if ( xParent.is() )
998 // Let parent notify "REMOVED" event.
999 com::sun::star::ucb::ContentEvent aEvt(
1000 static_cast< cppu::OWeakObject * >( xParent.get() ),
1001 com::sun::star::ucb::ContentAction::REMOVED,
1002 this,
1003 xParent->getIdentifier() );
1004 xParent->notifyContentEvent( aEvt );
1007 // Notify "DELETED" event.
1008 com::sun::star::ucb::ContentEvent aEvt1(
1009 static_cast< cppu::OWeakObject * >( this ),
1010 com::sun::star::ucb::ContentAction::DELETED,
1011 this,
1012 getIdentifier() );
1013 notifyContentEvent( aEvt1 );
1015 m_xProvider->removeContent( this );
1018 //=========================================================================
1019 sal_Bool ContentImplHelper::exchange(
1020 const uno::Reference< com::sun::star::ucb::XContentIdentifier >& rNewId )
1022 uno::Reference< com::sun::star::ucb::XContent > xThis = this;
1024 osl::ClearableMutexGuard aGuard( m_aMutex );
1026 rtl::Reference< ContentImplHelper > xContent
1027 = m_xProvider->queryExistingContent( rNewId );
1028 if ( xContent.is() )
1030 // @@@
1031 // Big trouble. Another object with the new identity exists.
1032 // How shall I mutate to / merge with the other object?
1033 return sal_False;
1036 uno::Reference< com::sun::star::ucb::XContentIdentifier > xOldId
1037 = getIdentifier();
1039 // Re-insert at provider.
1040 m_xProvider->removeContent( this );
1041 m_xIdentifier = rNewId;
1042 m_xProvider->registerNewContent( this );
1044 aGuard.clear();
1046 // Notify "EXCHANGED" event.
1047 com::sun::star::ucb::ContentEvent aEvt(
1048 static_cast< cppu::OWeakObject * >( this ),
1049 com::sun::star::ucb::ContentAction::EXCHANGED,
1050 this,
1051 xOldId );
1052 notifyContentEvent( aEvt );
1053 return sal_True;
1056 //=========================================================================
1057 uno::Reference< com::sun::star::ucb::XCommandInfo >
1058 ContentImplHelper::getCommandInfo(
1059 const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv,
1060 sal_Bool bCache )
1062 osl::MutexGuard aGuard( m_aMutex );
1064 if ( !m_pImpl->m_xCommandsInfo.is() )
1065 m_pImpl->m_xCommandsInfo
1066 = new CommandProcessorInfo( xEnv, this );
1067 else if ( !bCache )
1068 m_pImpl->m_xCommandsInfo->reset();
1070 return uno::Reference< com::sun::star::ucb::XCommandInfo >(
1071 m_pImpl->m_xCommandsInfo.get() );
1074 //=========================================================================
1075 uno::Reference< beans::XPropertySetInfo >
1076 ContentImplHelper::getPropertySetInfo(
1077 const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv,
1078 sal_Bool bCache )
1080 osl::MutexGuard aGuard( m_aMutex );
1082 if ( !m_pImpl->m_xPropSetInfo.is() )
1083 m_pImpl->m_xPropSetInfo
1084 = new PropertySetInfo( xEnv, this );
1085 else if ( !bCache )
1086 m_pImpl->m_xPropSetInfo->reset();
1088 return uno::Reference< beans::XPropertySetInfo >(
1089 m_pImpl->m_xPropSetInfo.get() );
1092 } // namespace ucbhelper
1094 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */