1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * Copyright 2000, 2010 Oracle and/or its affiliates.
6 * OpenOffice.org - a multi-platform office productivity suite
8 * This file is part of OpenOffice.org.
10 * OpenOffice.org is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License version 3
12 * only, as published by the Free Software Foundation.
14 * OpenOffice.org is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License version 3 for more details
18 * (a copy is included in the LICENSE file that accompanied this code).
20 * You should have received a copy of the GNU Lesser General Public License
21 * version 3 along with OpenOffice.org. If not, see
22 * <http://www.openoffice.org/license.html>
23 * for a copy of the LGPLv3 License.
25 ************************************************************************/
27 #include "precompiled_comphelper.hxx"
29 #include "comphelper_module.hxx"
30 #include "comphelper/anytostring.hxx"
31 #include "comphelper/anycompare.hxx"
32 #include "comphelper/componentbase.hxx"
33 #include "comphelper/componentcontext.hxx"
34 #include "comphelper/extract.hxx"
36 /** === begin UNO includes === **/
37 #include <com/sun/star/container/XEnumerableMap.hpp>
38 #include <com/sun/star/lang/XInitialization.hpp>
39 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
40 #include <com/sun/star/beans/Pair.hpp>
41 #include <com/sun/star/lang/XServiceInfo.hpp>
42 /** === end UNO includes === **/
44 #include <cppuhelper/compbase3.hxx>
45 #include <cppuhelper/implbase1.hxx>
46 #include <rtl/math.hxx>
47 #include <rtl/ustrbuf.hxx>
48 #include <typelib/typedescription.hxx>
51 #include <boost/shared_ptr.hpp>
53 //........................................................................
56 //........................................................................
58 /** === begin UNO using === **/
59 using ::com::sun::star::uno::Reference
;
60 using ::com::sun::star::uno::XInterface
;
61 using ::com::sun::star::uno::UNO_QUERY
;
62 using ::com::sun::star::uno::UNO_QUERY_THROW
;
63 using ::com::sun::star::uno::UNO_SET_THROW
;
64 using ::com::sun::star::uno::Exception
;
65 using ::com::sun::star::uno::RuntimeException
;
66 using ::com::sun::star::uno::Any
;
67 using ::com::sun::star::uno::makeAny
;
68 using ::com::sun::star::uno::Sequence
;
69 using ::com::sun::star::uno::Type
;
70 using ::com::sun::star::container::XEnumerableMap
;
71 using ::com::sun::star::lang::NoSupportException
;
72 using ::com::sun::star::beans::IllegalTypeException
;
73 using ::com::sun::star::container::NoSuchElementException
;
74 using ::com::sun::star::lang::IllegalArgumentException
;
75 using ::com::sun::star::lang::XInitialization
;
76 using ::com::sun::star::ucb::AlreadyInitializedException
;
77 using ::com::sun::star::beans::Pair
;
78 using ::com::sun::star::uno::TypeClass
;
79 using ::com::sun::star::uno::TypeClass_VOID
;
80 using ::com::sun::star::uno::TypeClass_UNKNOWN
;
81 using ::com::sun::star::uno::TypeClass_ANY
;
82 using ::com::sun::star::uno::TypeClass_EXCEPTION
;
83 using ::com::sun::star::uno::TypeClass_STRUCT
;
84 using ::com::sun::star::uno::TypeClass_UNION
;
85 using ::com::sun::star::uno::TypeClass_FLOAT
;
86 using ::com::sun::star::uno::TypeClass_DOUBLE
;
87 using ::com::sun::star::uno::TypeClass_INTERFACE
;
88 using ::com::sun::star::lang::XServiceInfo
;
89 using ::com::sun::star::uno::XComponentContext
;
90 using ::com::sun::star::container::XEnumeration
;
91 using ::com::sun::star::uno::TypeDescription
;
92 using ::com::sun::star::lang::WrappedTargetException
;
93 using ::com::sun::star::lang::DisposedException
;
94 /** === end UNO using === **/
96 //====================================================================
98 //====================================================================
99 class IMapModificationListener
;
100 typedef ::std::vector
< IMapModificationListener
* > MapListeners
;
102 typedef ::std::map
< Any
, Any
, LessPredicateAdapter
> KeyedValues
;
107 ::std::auto_ptr
< KeyedValues
> m_pValues
;
108 ::boost::shared_ptr
< IKeyPredicateLess
> m_pKeyCompare
;
110 MapListeners m_aModListeners
;
117 MapData( const MapData
& _source
)
118 :m_aKeyType( _source
.m_aKeyType
)
119 ,m_aValueType( _source
.m_aValueType
)
120 ,m_pValues( new KeyedValues( *_source
.m_pValues
) )
121 ,m_pKeyCompare( _source
.m_pKeyCompare
)
127 MapData
& operator=( const MapData
& _source
); // not implemented
130 //====================================================================
131 //= IMapModificationListener
132 //====================================================================
133 /** implemented by components who want to be notified of modifications in the MapData they work with
135 class SAL_NO_VTABLE IMapModificationListener
138 /// called when the map was modified
139 virtual void mapModified() = 0;
140 virtual ~IMapModificationListener()
145 //====================================================================
147 //====================================================================
148 //--------------------------------------------------------------------
149 static void lcl_registerMapModificationListener( MapData
& _mapData
, IMapModificationListener
& _listener
)
151 #if OSL_DEBUG_LEVEL > 0
152 for ( MapListeners::const_iterator lookup
= _mapData
.m_aModListeners
.begin();
153 lookup
!= _mapData
.m_aModListeners
.end();
157 OSL_ENSURE( *lookup
!= &_listener
, "lcl_registerMapModificationListener: this listener is already registered!" );
160 _mapData
.m_aModListeners
.push_back( &_listener
);
163 //--------------------------------------------------------------------
164 static void lcl_revokeMapModificationListener( MapData
& _mapData
, IMapModificationListener
& _listener
)
166 for ( MapListeners::iterator lookup
= _mapData
.m_aModListeners
.begin();
167 lookup
!= _mapData
.m_aModListeners
.end();
171 if ( *lookup
== &_listener
)
173 _mapData
.m_aModListeners
.erase( lookup
);
177 OSL_ENSURE( false, "lcl_revokeMapModificationListener: the listener is not registered!" );
180 //--------------------------------------------------------------------
181 static void lcl_notifyMapDataListeners_nothrow( const MapData
& _mapData
)
183 for ( MapListeners::const_iterator loop
= _mapData
.m_aModListeners
.begin();
184 loop
!= _mapData
.m_aModListeners
.end();
188 (*loop
)->mapModified();
192 //====================================================================
194 //====================================================================
195 typedef ::cppu::WeakAggComponentImplHelper3
< XInitialization
200 class COMPHELPER_DLLPRIVATE EnumerableMap
:public Map_IFace
201 ,public ComponentBase
204 EnumerableMap( const ComponentContext
& _rContext
);
205 virtual ~EnumerableMap();
208 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
) throw (Exception
, RuntimeException
);
211 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::container::XEnumeration
> SAL_CALL
createKeyEnumeration( ::sal_Bool _Isolated
) throw (::com::sun::star::lang::NoSupportException
, ::com::sun::star::uno::RuntimeException
);
212 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::container::XEnumeration
> SAL_CALL
createValueEnumeration( ::sal_Bool _Isolated
) throw (::com::sun::star::lang::NoSupportException
, ::com::sun::star::uno::RuntimeException
);
213 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::container::XEnumeration
> SAL_CALL
createElementEnumeration( ::sal_Bool _Isolated
) throw (::com::sun::star::lang::NoSupportException
, ::com::sun::star::uno::RuntimeException
);
216 virtual Type SAL_CALL
getKeyType() throw (RuntimeException
);
217 virtual Type SAL_CALL
getValueType() throw (RuntimeException
);
218 virtual void SAL_CALL
clear( ) throw (NoSupportException
, RuntimeException
);
219 virtual ::sal_Bool SAL_CALL
containsKey( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
);
220 virtual ::sal_Bool SAL_CALL
containsValue( const Any
& _value
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
);
221 virtual Any SAL_CALL
get( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
);
222 virtual Any SAL_CALL
put( const Any
& _key
, const Any
& _value
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, RuntimeException
);
223 virtual Any SAL_CALL
remove( const Any
& _key
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
);
225 // XElementAccess (base of XMap)
226 virtual Type SAL_CALL
getElementType() throw (RuntimeException
);
227 virtual ::sal_Bool SAL_CALL
hasElements() throw (RuntimeException
);
230 virtual ::rtl::OUString SAL_CALL
getImplementationName( ) throw (RuntimeException
);
231 virtual ::sal_Bool SAL_CALL
supportsService( const ::rtl::OUString
& ServiceName
) throw (RuntimeException
);
232 virtual Sequence
< ::rtl::OUString
> SAL_CALL
getSupportedServiceNames( ) throw (RuntimeException
);
235 // XServiceInfo, static version (used for component registration)
236 static ::rtl::OUString SAL_CALL
getImplementationName_static( );
237 static Sequence
< ::rtl::OUString
> SAL_CALL
getSupportedServiceNames_static( );
238 static Reference
< XInterface
> SAL_CALL
Create( const Reference
< XComponentContext
>& );
241 void impl_initValues_throw( const Sequence
< Pair
< Any
, Any
> >& _initialValues
);
243 /// throws a IllegalTypeException if the given value is not compatible with our ValueType
244 void impl_checkValue_throw( const Any
& _value
) const;
245 void impl_checkKey_throw( const Any
& _key
) const;
246 void impl_checkNaN_throw( const Any
& _keyOrValue
, const Type
& _keyOrValueType
) const;
247 void impl_checkMutable_throw() const;
250 ::osl::Mutex m_aMutex
;
251 ComponentContext m_aContext
;
254 ::std::vector
< ::com::sun::star::uno::WeakReference
< XInterface
> >
255 m_aDependentComponents
;
258 //====================================================================
260 //====================================================================
263 eKeys
, eValues
, eBoth
266 //====================================================================
268 //====================================================================
269 class MapEnumerator
: public IMapModificationListener
272 MapEnumerator( ::cppu::OWeakObject
& _rParent
, MapData
& _mapData
, const EnumerationType _type
)
273 :m_rParent( _rParent
)
274 ,m_rMapData( _mapData
)
276 ,m_mapPos( _mapData
.m_pValues
->begin() )
279 lcl_registerMapModificationListener( m_rMapData
, *this );
282 virtual ~MapEnumerator()
291 lcl_revokeMapModificationListener( m_rMapData
, *this );
296 // XEnumeration equivalents
297 ::sal_Bool
hasMoreElements();
300 // IMapModificationListener
301 virtual void mapModified();
304 ::cppu::OWeakObject
& m_rParent
;
306 const EnumerationType m_eType
;
307 KeyedValues::const_iterator m_mapPos
;
311 MapEnumerator(); // not implemented
312 MapEnumerator( const MapEnumerator
& ); // not implemented
313 MapEnumerator
& operator=( const MapEnumerator
& ); // not implemented
316 //====================================================================
318 //====================================================================
319 typedef ::cppu::WeakImplHelper1
< XEnumeration
320 > MapEnumeration_Base
;
321 class MapEnumeration
:public ComponentBase
322 ,public MapEnumeration_Base
325 MapEnumeration( ::cppu::OWeakObject
& _parentMap
, MapData
& _mapData
, ::cppu::OBroadcastHelper
& _rBHelper
,
326 const EnumerationType _type
, const bool _isolated
)
327 :ComponentBase( _rBHelper
, ComponentBase::NoInitializationNeeded() )
328 ,m_xKeepMapAlive( _parentMap
)
329 ,m_pMapDataCopy( _isolated
? new MapData( _mapData
) : NULL
)
330 ,m_aEnumerator( *this, _isolated
? *m_pMapDataCopy
: _mapData
, _type
)
335 virtual ::sal_Bool SAL_CALL
hasMoreElements( ) throw (RuntimeException
);
336 virtual Any SAL_CALL
nextElement( ) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
);
339 virtual ~MapEnumeration()
343 ::osl::MutexGuard
aGuard( getMutex() );
344 m_aEnumerator
.dispose();
345 m_pMapDataCopy
.reset();
350 // sicne we share our mutex with the main map, we need to keep it alive as long as we live
351 Reference
< XInterface
> m_xKeepMapAlive
;
352 ::std::auto_ptr
< MapData
> m_pMapDataCopy
;
353 MapEnumerator m_aEnumerator
;
356 //====================================================================
358 //====================================================================
359 //--------------------------------------------------------------------
360 EnumerableMap::EnumerableMap( const ComponentContext
& _rContext
)
361 :Map_IFace( m_aMutex
)
362 ,ComponentBase( Map_IFace::rBHelper
)
363 ,m_aContext( _rContext
)
367 //--------------------------------------------------------------------
368 EnumerableMap::~EnumerableMap()
370 if ( !impl_isDisposed() )
377 //--------------------------------------------------------------------
378 void SAL_CALL
EnumerableMap::initialize( const Sequence
< Any
>& _arguments
) throw (Exception
, RuntimeException
)
380 ComponentMethodGuard
aGuard( *this, ComponentMethodGuard::WithoutInit
);
381 if ( impl_isInitialized_nothrow() )
382 throw AlreadyInitializedException();
384 sal_Int32 nArgumentCount
= _arguments
.getLength();
385 if ( ( nArgumentCount
!= 2 ) && ( nArgumentCount
!= 3 ) )
386 throw IllegalArgumentException();
388 Type aKeyType
, aValueType
;
389 if ( !( _arguments
[0] >>= aKeyType
) )
390 throw IllegalArgumentException( ::rtl::OUString::createFromAscii( "com.sun.star.uno.Type expected." ), *this, 1 );
391 if ( !( _arguments
[1] >>= aValueType
) )
392 throw IllegalArgumentException( ::rtl::OUString::createFromAscii( "com.sun.star.uno.Type expected." ), *this, 2 );
394 Sequence
< Pair
< Any
, Any
> > aInitialValues
;
395 bool bMutable
= true;
396 if ( nArgumentCount
== 3 )
398 if ( !( _arguments
[2] >>= aInitialValues
) )
399 throw IllegalArgumentException( ::rtl::OUString::createFromAscii( "[]com.sun.star.beans.Pair<any,any> expected." ), *this, 2 );
403 // for the value, anything is allowed, except VOID
404 if ( ( aValueType
.getTypeClass() == TypeClass_VOID
) || ( aValueType
.getTypeClass() == TypeClass_UNKNOWN
) )
405 throw IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unsupported value type." ) ), *this );
407 // create the comparator for the KeyType, and throw if the type is not supported
408 ::std::auto_ptr
< IKeyPredicateLess
> pComparator( getStandardLessPredicate( aKeyType
, NULL
) );
409 if ( !pComparator
.get() )
410 throw IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unsupported key type." ) ), *this );
413 m_aData
.m_aKeyType
= aKeyType
;
414 m_aData
.m_aValueType
= aValueType
;
415 m_aData
.m_pKeyCompare
= pComparator
;
416 m_aData
.m_pValues
.reset( new KeyedValues( *m_aData
.m_pKeyCompare
) );
417 m_aData
.m_bMutable
= bMutable
;
419 if ( aInitialValues
.getLength() )
420 impl_initValues_throw( aInitialValues
);
425 //--------------------------------------------------------------------
426 void EnumerableMap::impl_initValues_throw( const Sequence
< Pair
< Any
, Any
> >& _initialValues
)
428 OSL_PRECOND( m_aData
.m_pValues
.get() && m_aData
.m_pValues
->empty(), "EnumerableMap::impl_initValues_throw: illegal call!" );
429 if ( !m_aData
.m_pValues
.get() || !m_aData
.m_pValues
->empty() )
430 throw RuntimeException();
432 const Pair
< Any
, Any
>* mapping
= _initialValues
.getConstArray();
433 const Pair
< Any
, Any
>* mappingEnd
= mapping
+ _initialValues
.getLength();
435 for ( ; mapping
!= mappingEnd
; ++mapping
)
437 impl_checkValue_throw( mapping
->Second
);
438 (*m_aData
.m_pValues
)[ mapping
->First
] = mapping
->Second
;
442 //--------------------------------------------------------------------
443 void EnumerableMap::impl_checkValue_throw( const Any
& _value
) const
445 if ( !_value
.hasValue() )
446 // nothing to do, NULL values are always allowed, regardless of the ValueType
449 TypeClass eAllowedTypeClass
= m_aData
.m_aValueType
.getTypeClass();
452 switch ( eAllowedTypeClass
)
455 bValid
= ( _value
.getValueTypeClass() == eAllowedTypeClass
);
460 case TypeClass_INTERFACE
:
462 // special treatment: _value might contain the proper type, but the interface
463 // might actually be NULL. Which is still valid ...
464 if ( m_aData
.m_aValueType
.isAssignableFrom( _value
.getValueType() ) )
465 // this also catches the special case where XFoo is our value type,
466 // and _value contains a NULL-reference to XFoo, or a derived type
470 Reference
< XInterface
> xValue( _value
, UNO_QUERY
);
473 // XInterface is not-NULL, but is X(ValueType) not-NULL, too?
474 xValue
.set( xValue
->queryInterface( m_aData
.m_aValueType
), UNO_QUERY
);
475 bValid
= xValue
.is();
479 case TypeClass_EXCEPTION
:
480 case TypeClass_STRUCT
:
481 case TypeClass_UNION
:
483 // values are accepted if and only if their type equals, or is derived from, our value type
485 if ( _value
.getValueTypeClass() != eAllowedTypeClass
)
489 const TypeDescription
aValueTypeDesc( _value
.getValueType() );
490 const TypeDescription
aRequiredTypeDesc( m_aData
.m_aValueType
);
492 const _typelib_CompoundTypeDescription
* pValueCompoundTypeDesc
=
493 reinterpret_cast< const _typelib_CompoundTypeDescription
* >( aValueTypeDesc
.get() );
495 while ( pValueCompoundTypeDesc
)
497 if ( typelib_typedescription_equals( &pValueCompoundTypeDesc
->aBase
, aRequiredTypeDesc
.get() ) )
499 pValueCompoundTypeDesc
= pValueCompoundTypeDesc
->pBaseTypeDescription
;
501 bValid
= ( pValueCompoundTypeDesc
!= NULL
);
509 ::rtl::OUStringBuffer aMessage
;
510 aMessage
.appendAscii( "Incompatible value type. Found '" );
511 aMessage
.append( _value
.getValueTypeName() );
512 aMessage
.appendAscii( "', where '" );
513 aMessage
.append( m_aData
.m_aValueType
.getTypeName() );
514 aMessage
.appendAscii( "' (or compatible type) is expected." );
515 throw IllegalTypeException( aMessage
.makeStringAndClear(), *const_cast< EnumerableMap
* >( this ) );
518 impl_checkNaN_throw( _value
, m_aData
.m_aValueType
);
521 //--------------------------------------------------------------------
522 void EnumerableMap::impl_checkNaN_throw( const Any
& _keyOrValue
, const Type
& _keyOrValueType
) const
524 if ( ( _keyOrValueType
.getTypeClass() == TypeClass_DOUBLE
)
525 || ( _keyOrValueType
.getTypeClass() == TypeClass_FLOAT
)
529 if ( _keyOrValue
>>= nValue
)
530 if ( ::rtl::math::isNan( nValue
) )
531 throw IllegalArgumentException(
532 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NaN (not-a-number) not supported by this implementation." ) ),
533 *const_cast< EnumerableMap
* >( this ), 0 );
534 // (note that the case of _key not containing a float/double value is handled in the
535 // respective IKeyPredicateLess implementation, so there's no need to handle this here.)
539 //--------------------------------------------------------------------
540 void EnumerableMap::impl_checkKey_throw( const Any
& _key
) const
542 if ( !_key
.hasValue() )
543 throw IllegalArgumentException(
544 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NULL keys not supported by this implementation." ) ),
545 *const_cast< EnumerableMap
* >( this ), 0 );
547 impl_checkNaN_throw( _key
, m_aData
.m_aKeyType
);
550 //--------------------------------------------------------------------
551 void EnumerableMap::impl_checkMutable_throw() const
553 if ( !m_aData
.m_bMutable
)
554 throw NoSupportException(
555 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The map is immutable." ) ),
556 *const_cast< EnumerableMap
* >( this ) );
559 //--------------------------------------------------------------------
560 Reference
< XEnumeration
> SAL_CALL
EnumerableMap::createKeyEnumeration( ::sal_Bool _Isolated
) throw (NoSupportException
, RuntimeException
)
562 ComponentMethodGuard
aGuard( *this );
563 return new MapEnumeration( *this, m_aData
, getBroadcastHelper(), eKeys
, _Isolated
);
566 //--------------------------------------------------------------------
567 Reference
< XEnumeration
> SAL_CALL
EnumerableMap::createValueEnumeration( ::sal_Bool _Isolated
) throw (NoSupportException
, RuntimeException
)
569 ComponentMethodGuard
aGuard( *this );
570 return new MapEnumeration( *this, m_aData
, getBroadcastHelper(), eValues
, _Isolated
);
573 //--------------------------------------------------------------------
574 Reference
< XEnumeration
> SAL_CALL
EnumerableMap::createElementEnumeration( ::sal_Bool _Isolated
) throw (NoSupportException
, RuntimeException
)
576 ComponentMethodGuard
aGuard( *this );
577 return new MapEnumeration( *this, m_aData
, getBroadcastHelper(), eBoth
, _Isolated
);
580 //--------------------------------------------------------------------
581 Type SAL_CALL
EnumerableMap::getKeyType() throw (RuntimeException
)
583 ComponentMethodGuard
aGuard( *this );
584 return m_aData
.m_aKeyType
;
587 //--------------------------------------------------------------------
588 Type SAL_CALL
EnumerableMap::getValueType() throw (RuntimeException
)
590 ComponentMethodGuard
aGuard( *this );
591 return m_aData
.m_aValueType
;
594 //--------------------------------------------------------------------
595 void SAL_CALL
EnumerableMap::clear( ) throw (NoSupportException
, RuntimeException
)
597 ComponentMethodGuard
aGuard( *this );
598 impl_checkMutable_throw();
600 m_aData
.m_pValues
->clear();
602 lcl_notifyMapDataListeners_nothrow( m_aData
);
605 //--------------------------------------------------------------------
606 ::sal_Bool SAL_CALL
EnumerableMap::containsKey( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
)
608 ComponentMethodGuard
aGuard( *this );
609 impl_checkKey_throw( _key
);
611 KeyedValues::const_iterator pos
= m_aData
.m_pValues
->find( _key
);
612 return ( pos
!= m_aData
.m_pValues
->end() );
615 //--------------------------------------------------------------------
616 ::sal_Bool SAL_CALL
EnumerableMap::containsValue( const Any
& _value
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
)
618 ComponentMethodGuard
aGuard( *this );
619 impl_checkValue_throw( _value
);
621 for ( KeyedValues::const_iterator mapping
= m_aData
.m_pValues
->begin();
622 mapping
!= m_aData
.m_pValues
->end();
626 if ( mapping
->second
== _value
)
632 //--------------------------------------------------------------------
633 Any SAL_CALL
EnumerableMap::get( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
)
635 ComponentMethodGuard
aGuard( *this );
636 impl_checkKey_throw( _key
);
638 KeyedValues::const_iterator pos
= m_aData
.m_pValues
->find( _key
);
639 if ( pos
== m_aData
.m_pValues
->end() )
640 throw NoSuchElementException( anyToString( _key
), *this );
645 //--------------------------------------------------------------------
646 Any SAL_CALL
EnumerableMap::put( const Any
& _key
, const Any
& _value
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, RuntimeException
)
648 ComponentMethodGuard
aGuard( *this );
649 impl_checkMutable_throw();
650 impl_checkKey_throw( _key
);
651 impl_checkValue_throw( _value
);
655 KeyedValues::iterator pos
= m_aData
.m_pValues
->find( _key
);
656 if ( pos
!= m_aData
.m_pValues
->end() )
658 previousValue
= pos
->second
;
659 pos
->second
= _value
;
663 (*m_aData
.m_pValues
)[ _key
] = _value
;
666 lcl_notifyMapDataListeners_nothrow( m_aData
);
668 return previousValue
;
671 //--------------------------------------------------------------------
672 Any SAL_CALL
EnumerableMap::remove( const Any
& _key
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
)
674 ComponentMethodGuard
aGuard( *this );
675 impl_checkMutable_throw();
676 impl_checkKey_throw( _key
);
680 KeyedValues::iterator pos
= m_aData
.m_pValues
->find( _key
);
681 if ( pos
!= m_aData
.m_pValues
->end() )
683 previousValue
= pos
->second
;
684 m_aData
.m_pValues
->erase( pos
);
687 lcl_notifyMapDataListeners_nothrow( m_aData
);
689 return previousValue
;
692 //--------------------------------------------------------------------
693 Type SAL_CALL
EnumerableMap::getElementType() throw (RuntimeException
)
695 return ::cppu::UnoType
< Pair
< Any
, Any
> >::get();
698 //--------------------------------------------------------------------
699 ::sal_Bool SAL_CALL
EnumerableMap::hasElements() throw (RuntimeException
)
701 ComponentMethodGuard
aGuard( *this );
702 return m_aData
.m_pValues
->empty();
705 //--------------------------------------------------------------------
706 ::rtl::OUString SAL_CALL
EnumerableMap::getImplementationName( ) throw (RuntimeException
)
708 return getImplementationName_static();
711 //--------------------------------------------------------------------
712 ::sal_Bool SAL_CALL
EnumerableMap::supportsService( const ::rtl::OUString
& _serviceName
) throw (RuntimeException
)
714 Sequence
< ::rtl::OUString
> aServices( getSupportedServiceNames() );
715 for ( sal_Int32 i
=0; i
<aServices
.getLength(); ++i
)
716 if ( _serviceName
== aServices
[i
] )
721 //--------------------------------------------------------------------
722 Sequence
< ::rtl::OUString
> SAL_CALL
EnumerableMap::getSupportedServiceNames( ) throw (RuntimeException
)
724 return getSupportedServiceNames_static();
727 //--------------------------------------------------------------------
728 ::rtl::OUString SAL_CALL
EnumerableMap::getImplementationName_static( )
730 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.comphelper.EnumerableMap" ) );
733 //--------------------------------------------------------------------
734 Sequence
< ::rtl::OUString
> SAL_CALL
EnumerableMap::getSupportedServiceNames_static( )
736 Sequence
< ::rtl::OUString
> aServiceNames(1);
737 aServiceNames
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.container.EnumerableMap" ) );
738 return aServiceNames
;
741 //--------------------------------------------------------------------
742 Reference
< XInterface
> SAL_CALL
EnumerableMap::Create( const Reference
< XComponentContext
>& _context
)
744 return *new EnumerableMap( ComponentContext( _context
) );
747 //====================================================================
749 //====================================================================
750 //--------------------------------------------------------------------
751 ::sal_Bool
MapEnumerator::hasMoreElements()
754 throw DisposedException( ::rtl::OUString(), m_rParent
);
755 return m_mapPos
!= m_rMapData
.m_pValues
->end();
758 //--------------------------------------------------------------------
759 Any
MapEnumerator::nextElement()
762 throw DisposedException( ::rtl::OUString(), m_rParent
);
763 if ( m_mapPos
== m_rMapData
.m_pValues
->end() )
764 throw NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No more elements." ) ), m_rParent
);
769 case eKeys
: aNextElement
= m_mapPos
->first
; break;
770 case eValues
: aNextElement
= m_mapPos
->second
; break;
771 case eBoth
: aNextElement
<<= Pair
< Any
, Any
>( m_mapPos
->first
, m_mapPos
->second
); break;
777 //--------------------------------------------------------------------
778 void MapEnumerator::mapModified()
783 //====================================================================
784 //= MapEnumeration - implementation
785 //====================================================================
786 //--------------------------------------------------------------------
787 ::sal_Bool SAL_CALL
MapEnumeration::hasMoreElements( ) throw (RuntimeException
)
789 ComponentMethodGuard
aGuard( *this );
790 return m_aEnumerator
.hasMoreElements();
793 //--------------------------------------------------------------------
794 Any SAL_CALL
MapEnumeration::nextElement( ) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
)
796 ComponentMethodGuard
aGuard( *this );
797 return m_aEnumerator
.nextElement();
800 //........................................................................
801 } // namespace comphelper
802 //........................................................................
804 void createRegistryInfo_Map()
806 ::comphelper::module::OAutoRegistration
< ::comphelper::EnumerableMap
> aAutoRegistration
;