1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include "comphelper_module.hxx"
22 #include "comphelper/anytostring.hxx"
23 #include "comphelper/anycompare.hxx"
24 #include "comphelper/componentbase.hxx"
25 #include "comphelper/extract.hxx"
27 #include <com/sun/star/container/XEnumerableMap.hpp>
28 #include <com/sun/star/lang/XInitialization.hpp>
29 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
30 #include <com/sun/star/beans/Pair.hpp>
31 #include <com/sun/star/lang/XServiceInfo.hpp>
33 #include <cppuhelper/compbase3.hxx>
34 #include <cppuhelper/implbase1.hxx>
35 #include <rtl/math.hxx>
36 #include <rtl/ustrbuf.hxx>
37 #include <typelib/typedescription.hxx>
40 #include <boost/shared_ptr.hpp>
42 //........................................................................
45 //........................................................................
47 /** === begin UNO using === **/
48 using ::com::sun::star::uno::Reference
;
49 using ::com::sun::star::uno::XInterface
;
50 using ::com::sun::star::uno::UNO_QUERY
;
51 using ::com::sun::star::uno::UNO_QUERY_THROW
;
52 using ::com::sun::star::uno::UNO_SET_THROW
;
53 using ::com::sun::star::uno::Exception
;
54 using ::com::sun::star::uno::RuntimeException
;
55 using ::com::sun::star::uno::Any
;
56 using ::com::sun::star::uno::makeAny
;
57 using ::com::sun::star::uno::Sequence
;
58 using ::com::sun::star::uno::Type
;
59 using ::com::sun::star::container::XEnumerableMap
;
60 using ::com::sun::star::lang::NoSupportException
;
61 using ::com::sun::star::beans::IllegalTypeException
;
62 using ::com::sun::star::container::NoSuchElementException
;
63 using ::com::sun::star::lang::IllegalArgumentException
;
64 using ::com::sun::star::lang::XInitialization
;
65 using ::com::sun::star::ucb::AlreadyInitializedException
;
66 using ::com::sun::star::beans::Pair
;
67 using ::com::sun::star::uno::TypeClass
;
68 using ::com::sun::star::uno::TypeClass_VOID
;
69 using ::com::sun::star::uno::TypeClass_UNKNOWN
;
70 using ::com::sun::star::uno::TypeClass_ANY
;
71 using ::com::sun::star::uno::TypeClass_EXCEPTION
;
72 using ::com::sun::star::uno::TypeClass_STRUCT
;
73 using ::com::sun::star::uno::TypeClass_UNION
;
74 using ::com::sun::star::uno::TypeClass_FLOAT
;
75 using ::com::sun::star::uno::TypeClass_DOUBLE
;
76 using ::com::sun::star::uno::TypeClass_INTERFACE
;
77 using ::com::sun::star::lang::XServiceInfo
;
78 using ::com::sun::star::uno::XComponentContext
;
79 using ::com::sun::star::container::XEnumeration
;
80 using ::com::sun::star::uno::TypeDescription
;
81 using ::com::sun::star::lang::WrappedTargetException
;
82 using ::com::sun::star::lang::DisposedException
;
83 /** === end UNO using === **/
85 //====================================================================
87 //====================================================================
88 class IMapModificationListener
;
89 typedef ::std::vector
< IMapModificationListener
* > MapListeners
;
91 typedef ::std::map
< Any
, Any
, LessPredicateAdapter
> KeyedValues
;
96 ::std::auto_ptr
< KeyedValues
> m_pValues
;
97 ::boost::shared_ptr
< IKeyPredicateLess
> m_pKeyCompare
;
99 MapListeners m_aModListeners
;
106 MapData( const MapData
& _source
)
107 :m_aKeyType( _source
.m_aKeyType
)
108 ,m_aValueType( _source
.m_aValueType
)
109 ,m_pValues( new KeyedValues( *_source
.m_pValues
) )
110 ,m_pKeyCompare( _source
.m_pKeyCompare
)
116 MapData
& operator=( const MapData
& _source
); // not implemented
119 //====================================================================
120 //= IMapModificationListener
121 //====================================================================
122 /** implemented by components who want to be notified of modifications in the MapData they work with
124 class SAL_NO_VTABLE IMapModificationListener
127 /// called when the map was modified
128 virtual void mapModified() = 0;
129 virtual ~IMapModificationListener()
134 //====================================================================
136 //====================================================================
137 //--------------------------------------------------------------------
138 static void lcl_registerMapModificationListener( MapData
& _mapData
, IMapModificationListener
& _listener
)
140 #if OSL_DEBUG_LEVEL > 0
141 for ( MapListeners::const_iterator lookup
= _mapData
.m_aModListeners
.begin();
142 lookup
!= _mapData
.m_aModListeners
.end();
146 OSL_ENSURE( *lookup
!= &_listener
, "lcl_registerMapModificationListener: this listener is already registered!" );
149 _mapData
.m_aModListeners
.push_back( &_listener
);
152 //--------------------------------------------------------------------
153 static void lcl_revokeMapModificationListener( MapData
& _mapData
, IMapModificationListener
& _listener
)
155 for ( MapListeners::iterator lookup
= _mapData
.m_aModListeners
.begin();
156 lookup
!= _mapData
.m_aModListeners
.end();
160 if ( *lookup
== &_listener
)
162 _mapData
.m_aModListeners
.erase( lookup
);
166 OSL_FAIL( "lcl_revokeMapModificationListener: the listener is not registered!" );
169 //--------------------------------------------------------------------
170 static void lcl_notifyMapDataListeners_nothrow( const MapData
& _mapData
)
172 for ( MapListeners::const_iterator loop
= _mapData
.m_aModListeners
.begin();
173 loop
!= _mapData
.m_aModListeners
.end();
177 (*loop
)->mapModified();
181 //====================================================================
183 //====================================================================
184 typedef ::cppu::WeakAggComponentImplHelper3
< XInitialization
189 class COMPHELPER_DLLPRIVATE EnumerableMap
:public Map_IFace
190 ,public ComponentBase
194 virtual ~EnumerableMap();
197 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
) throw (Exception
, RuntimeException
);
200 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
);
201 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
);
202 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
);
205 virtual Type SAL_CALL
getKeyType() throw (RuntimeException
);
206 virtual Type SAL_CALL
getValueType() throw (RuntimeException
);
207 virtual void SAL_CALL
clear( ) throw (NoSupportException
, RuntimeException
);
208 virtual ::sal_Bool SAL_CALL
containsKey( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
);
209 virtual ::sal_Bool SAL_CALL
containsValue( const Any
& _value
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
);
210 virtual Any SAL_CALL
get( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
);
211 virtual Any SAL_CALL
put( const Any
& _key
, const Any
& _value
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, RuntimeException
);
212 virtual Any SAL_CALL
remove( const Any
& _key
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
);
214 // XElementAccess (base of XMap)
215 virtual Type SAL_CALL
getElementType() throw (RuntimeException
);
216 virtual ::sal_Bool SAL_CALL
hasElements() throw (RuntimeException
);
219 virtual ::rtl::OUString SAL_CALL
getImplementationName( ) throw (RuntimeException
);
220 virtual ::sal_Bool SAL_CALL
supportsService( const ::rtl::OUString
& ServiceName
) throw (RuntimeException
);
221 virtual Sequence
< ::rtl::OUString
> SAL_CALL
getSupportedServiceNames( ) throw (RuntimeException
);
224 // XServiceInfo, static version (used for component registration)
225 static ::rtl::OUString SAL_CALL
getImplementationName_static( );
226 static Sequence
< ::rtl::OUString
> SAL_CALL
getSupportedServiceNames_static( );
227 static Reference
< XInterface
> SAL_CALL
Create( const Reference
< XComponentContext
>& );
230 void impl_initValues_throw( const Sequence
< Pair
< Any
, Any
> >& _initialValues
);
232 /// throws a IllegalTypeException if the given value is not compatible with our ValueType
233 void impl_checkValue_throw( const Any
& _value
) const;
234 void impl_checkKey_throw( const Any
& _key
) const;
235 void impl_checkNaN_throw( const Any
& _keyOrValue
, const Type
& _keyOrValueType
) const;
236 void impl_checkMutable_throw() const;
239 ::osl::Mutex m_aMutex
;
242 ::std::vector
< ::com::sun::star::uno::WeakReference
< XInterface
> >
243 m_aDependentComponents
;
246 //====================================================================
248 //====================================================================
251 eKeys
, eValues
, eBoth
254 //====================================================================
256 //====================================================================
257 class MapEnumerator
: public IMapModificationListener
260 MapEnumerator( ::cppu::OWeakObject
& _rParent
, MapData
& _mapData
, const EnumerationType _type
)
261 :m_rParent( _rParent
)
262 ,m_rMapData( _mapData
)
264 ,m_mapPos( _mapData
.m_pValues
->begin() )
267 lcl_registerMapModificationListener( m_rMapData
, *this );
270 virtual ~MapEnumerator()
279 lcl_revokeMapModificationListener( m_rMapData
, *this );
284 // XEnumeration equivalents
285 ::sal_Bool
hasMoreElements();
288 // IMapModificationListener
289 virtual void mapModified();
292 ::cppu::OWeakObject
& m_rParent
;
294 const EnumerationType m_eType
;
295 KeyedValues::const_iterator m_mapPos
;
299 MapEnumerator(); // not implemented
300 MapEnumerator( const MapEnumerator
& ); // not implemented
301 MapEnumerator
& operator=( const MapEnumerator
& ); // not implemented
304 //====================================================================
306 //====================================================================
307 typedef ::cppu::WeakImplHelper1
< XEnumeration
308 > MapEnumeration_Base
;
309 class MapEnumeration
:public ComponentBase
310 ,public MapEnumeration_Base
313 MapEnumeration( ::cppu::OWeakObject
& _parentMap
, MapData
& _mapData
, ::cppu::OBroadcastHelper
& _rBHelper
,
314 const EnumerationType _type
, const bool _isolated
)
315 :ComponentBase( _rBHelper
, ComponentBase::NoInitializationNeeded() )
316 ,m_xKeepMapAlive( _parentMap
)
317 ,m_pMapDataCopy( _isolated
? new MapData( _mapData
) : NULL
)
318 ,m_aEnumerator( *this, _isolated
? *m_pMapDataCopy
: _mapData
, _type
)
323 virtual ::sal_Bool SAL_CALL
hasMoreElements( ) throw (RuntimeException
);
324 virtual Any SAL_CALL
nextElement( ) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
);
327 virtual ~MapEnumeration()
331 ::osl::MutexGuard
aGuard( getMutex() );
332 m_aEnumerator
.dispose();
333 m_pMapDataCopy
.reset();
338 // sicne we share our mutex with the main map, we need to keep it alive as long as we live
339 Reference
< XInterface
> m_xKeepMapAlive
;
340 ::std::auto_ptr
< MapData
> m_pMapDataCopy
;
341 MapEnumerator m_aEnumerator
;
344 //====================================================================
346 //====================================================================
347 //--------------------------------------------------------------------
348 EnumerableMap::EnumerableMap()
349 :Map_IFace( m_aMutex
)
350 ,ComponentBase( Map_IFace::rBHelper
)
354 //--------------------------------------------------------------------
355 EnumerableMap::~EnumerableMap()
357 if ( !impl_isDisposed() )
364 //--------------------------------------------------------------------
365 void SAL_CALL
EnumerableMap::initialize( const Sequence
< Any
>& _arguments
) throw (Exception
, RuntimeException
)
367 ComponentMethodGuard
aGuard( *this, ComponentMethodGuard::WithoutInit
);
368 if ( impl_isInitialized_nothrow() )
369 throw AlreadyInitializedException();
371 sal_Int32 nArgumentCount
= _arguments
.getLength();
372 if ( ( nArgumentCount
!= 2 ) && ( nArgumentCount
!= 3 ) )
373 throw IllegalArgumentException();
375 Type aKeyType
, aValueType
;
376 if ( !( _arguments
[0] >>= aKeyType
) )
377 throw IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Type expected.")), *this, 1 );
378 if ( !( _arguments
[1] >>= aValueType
) )
379 throw IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Type expected.")), *this, 2 );
381 Sequence
< Pair
< Any
, Any
> > aInitialValues
;
382 bool bMutable
= true;
383 if ( nArgumentCount
== 3 )
385 if ( !( _arguments
[2] >>= aInitialValues
) )
386 throw IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[]com.sun.star.beans.Pair<any,any> expected.")), *this, 2 );
390 // for the value, anything is allowed, except VOID
391 if ( ( aValueType
.getTypeClass() == TypeClass_VOID
) || ( aValueType
.getTypeClass() == TypeClass_UNKNOWN
) )
392 throw IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unsupported value type." ) ), *this );
394 // create the comparator for the KeyType, and throw if the type is not supported
395 ::std::auto_ptr
< IKeyPredicateLess
> pComparator( getStandardLessPredicate( aKeyType
, NULL
) );
396 if ( !pComparator
.get() )
397 throw IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unsupported key type." ) ), *this );
400 m_aData
.m_aKeyType
= aKeyType
;
401 m_aData
.m_aValueType
= aValueType
;
402 m_aData
.m_pKeyCompare
= pComparator
;
403 m_aData
.m_pValues
.reset( new KeyedValues( *m_aData
.m_pKeyCompare
) );
404 m_aData
.m_bMutable
= bMutable
;
406 if ( aInitialValues
.getLength() )
407 impl_initValues_throw( aInitialValues
);
412 //--------------------------------------------------------------------
413 void EnumerableMap::impl_initValues_throw( const Sequence
< Pair
< Any
, Any
> >& _initialValues
)
415 OSL_PRECOND( m_aData
.m_pValues
.get() && m_aData
.m_pValues
->empty(), "EnumerableMap::impl_initValues_throw: illegal call!" );
416 if ( !m_aData
.m_pValues
.get() || !m_aData
.m_pValues
->empty() )
417 throw RuntimeException();
419 const Pair
< Any
, Any
>* mapping
= _initialValues
.getConstArray();
420 const Pair
< Any
, Any
>* mappingEnd
= mapping
+ _initialValues
.getLength();
422 for ( ; mapping
!= mappingEnd
; ++mapping
)
424 impl_checkValue_throw( mapping
->Second
);
425 (*m_aData
.m_pValues
)[ mapping
->First
] = mapping
->Second
;
429 //--------------------------------------------------------------------
430 void EnumerableMap::impl_checkValue_throw( const Any
& _value
) const
432 if ( !_value
.hasValue() )
433 // nothing to do, NULL values are always allowed, regardless of the ValueType
436 TypeClass eAllowedTypeClass
= m_aData
.m_aValueType
.getTypeClass();
439 switch ( eAllowedTypeClass
)
442 bValid
= ( _value
.getValueTypeClass() == eAllowedTypeClass
);
447 case TypeClass_INTERFACE
:
449 // special treatment: _value might contain the proper type, but the interface
450 // might actually be NULL. Which is still valid ...
451 if ( m_aData
.m_aValueType
.isAssignableFrom( _value
.getValueType() ) )
452 // this also catches the special case where XFoo is our value type,
453 // and _value contains a NULL-reference to XFoo, or a derived type
457 Reference
< XInterface
> xValue( _value
, UNO_QUERY
);
460 // XInterface is not-NULL, but is X(ValueType) not-NULL, too?
461 xValue
.set( xValue
->queryInterface( m_aData
.m_aValueType
), UNO_QUERY
);
462 bValid
= xValue
.is();
466 case TypeClass_EXCEPTION
:
467 case TypeClass_STRUCT
:
468 case TypeClass_UNION
:
470 // values are accepted if and only if their type equals, or is derived from, our value type
472 if ( _value
.getValueTypeClass() != eAllowedTypeClass
)
476 const TypeDescription
aValueTypeDesc( _value
.getValueType() );
477 const TypeDescription
aRequiredTypeDesc( m_aData
.m_aValueType
);
479 const _typelib_CompoundTypeDescription
* pValueCompoundTypeDesc
=
480 reinterpret_cast< const _typelib_CompoundTypeDescription
* >( aValueTypeDesc
.get() );
482 while ( pValueCompoundTypeDesc
)
484 if ( typelib_typedescription_equals( &pValueCompoundTypeDesc
->aBase
, aRequiredTypeDesc
.get() ) )
486 pValueCompoundTypeDesc
= pValueCompoundTypeDesc
->pBaseTypeDescription
;
488 bValid
= ( pValueCompoundTypeDesc
!= NULL
);
496 ::rtl::OUStringBuffer aMessage
;
497 aMessage
.appendAscii( "Incompatible value type. Found '" );
498 aMessage
.append( _value
.getValueTypeName() );
499 aMessage
.appendAscii( "', where '" );
500 aMessage
.append( m_aData
.m_aValueType
.getTypeName() );
501 aMessage
.appendAscii( "' (or compatible type) is expected." );
502 throw IllegalTypeException( aMessage
.makeStringAndClear(), *const_cast< EnumerableMap
* >( this ) );
505 impl_checkNaN_throw( _value
, m_aData
.m_aValueType
);
508 //--------------------------------------------------------------------
509 void EnumerableMap::impl_checkNaN_throw( const Any
& _keyOrValue
, const Type
& _keyOrValueType
) const
511 if ( ( _keyOrValueType
.getTypeClass() == TypeClass_DOUBLE
)
512 || ( _keyOrValueType
.getTypeClass() == TypeClass_FLOAT
)
516 if ( _keyOrValue
>>= nValue
)
517 if ( ::rtl::math::isNan( nValue
) )
518 throw IllegalArgumentException(
519 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NaN (not-a-number) not supported by this implementation." ) ),
520 *const_cast< EnumerableMap
* >( this ), 0 );
521 // (note that the case of _key not containing a float/double value is handled in the
522 // respective IKeyPredicateLess implementation, so there's no need to handle this here.)
526 //--------------------------------------------------------------------
527 void EnumerableMap::impl_checkKey_throw( const Any
& _key
) const
529 if ( !_key
.hasValue() )
530 throw IllegalArgumentException(
531 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NULL keys not supported by this implementation." ) ),
532 *const_cast< EnumerableMap
* >( this ), 0 );
534 impl_checkNaN_throw( _key
, m_aData
.m_aKeyType
);
537 //--------------------------------------------------------------------
538 void EnumerableMap::impl_checkMutable_throw() const
540 if ( !m_aData
.m_bMutable
)
541 throw NoSupportException(
542 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The map is immutable." ) ),
543 *const_cast< EnumerableMap
* >( this ) );
546 //--------------------------------------------------------------------
547 Reference
< XEnumeration
> SAL_CALL
EnumerableMap::createKeyEnumeration( ::sal_Bool _Isolated
) throw (NoSupportException
, RuntimeException
)
549 ComponentMethodGuard
aGuard( *this );
550 return new MapEnumeration( *this, m_aData
, getBroadcastHelper(), eKeys
, _Isolated
);
553 //--------------------------------------------------------------------
554 Reference
< XEnumeration
> SAL_CALL
EnumerableMap::createValueEnumeration( ::sal_Bool _Isolated
) throw (NoSupportException
, RuntimeException
)
556 ComponentMethodGuard
aGuard( *this );
557 return new MapEnumeration( *this, m_aData
, getBroadcastHelper(), eValues
, _Isolated
);
560 //--------------------------------------------------------------------
561 Reference
< XEnumeration
> SAL_CALL
EnumerableMap::createElementEnumeration( ::sal_Bool _Isolated
) throw (NoSupportException
, RuntimeException
)
563 ComponentMethodGuard
aGuard( *this );
564 return new MapEnumeration( *this, m_aData
, getBroadcastHelper(), eBoth
, _Isolated
);
567 //--------------------------------------------------------------------
568 Type SAL_CALL
EnumerableMap::getKeyType() throw (RuntimeException
)
570 ComponentMethodGuard
aGuard( *this );
571 return m_aData
.m_aKeyType
;
574 //--------------------------------------------------------------------
575 Type SAL_CALL
EnumerableMap::getValueType() throw (RuntimeException
)
577 ComponentMethodGuard
aGuard( *this );
578 return m_aData
.m_aValueType
;
581 //--------------------------------------------------------------------
582 void SAL_CALL
EnumerableMap::clear( ) throw (NoSupportException
, RuntimeException
)
584 ComponentMethodGuard
aGuard( *this );
585 impl_checkMutable_throw();
587 m_aData
.m_pValues
->clear();
589 lcl_notifyMapDataListeners_nothrow( m_aData
);
592 //--------------------------------------------------------------------
593 ::sal_Bool SAL_CALL
EnumerableMap::containsKey( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
)
595 ComponentMethodGuard
aGuard( *this );
596 impl_checkKey_throw( _key
);
598 KeyedValues::const_iterator pos
= m_aData
.m_pValues
->find( _key
);
599 return ( pos
!= m_aData
.m_pValues
->end() );
602 //--------------------------------------------------------------------
603 ::sal_Bool SAL_CALL
EnumerableMap::containsValue( const Any
& _value
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
)
605 ComponentMethodGuard
aGuard( *this );
606 impl_checkValue_throw( _value
);
608 for ( KeyedValues::const_iterator mapping
= m_aData
.m_pValues
->begin();
609 mapping
!= m_aData
.m_pValues
->end();
613 if ( mapping
->second
== _value
)
619 //--------------------------------------------------------------------
620 Any SAL_CALL
EnumerableMap::get( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
)
622 ComponentMethodGuard
aGuard( *this );
623 impl_checkKey_throw( _key
);
625 KeyedValues::const_iterator pos
= m_aData
.m_pValues
->find( _key
);
626 if ( pos
== m_aData
.m_pValues
->end() )
627 throw NoSuchElementException( anyToString( _key
), *this );
632 //--------------------------------------------------------------------
633 Any SAL_CALL
EnumerableMap::put( const Any
& _key
, const Any
& _value
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, RuntimeException
)
635 ComponentMethodGuard
aGuard( *this );
636 impl_checkMutable_throw();
637 impl_checkKey_throw( _key
);
638 impl_checkValue_throw( _value
);
642 KeyedValues::iterator pos
= m_aData
.m_pValues
->find( _key
);
643 if ( pos
!= m_aData
.m_pValues
->end() )
645 previousValue
= pos
->second
;
646 pos
->second
= _value
;
650 (*m_aData
.m_pValues
)[ _key
] = _value
;
653 lcl_notifyMapDataListeners_nothrow( m_aData
);
655 return previousValue
;
658 //--------------------------------------------------------------------
659 Any SAL_CALL
EnumerableMap::remove( const Any
& _key
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
)
661 ComponentMethodGuard
aGuard( *this );
662 impl_checkMutable_throw();
663 impl_checkKey_throw( _key
);
667 KeyedValues::iterator pos
= m_aData
.m_pValues
->find( _key
);
668 if ( pos
!= m_aData
.m_pValues
->end() )
670 previousValue
= pos
->second
;
671 m_aData
.m_pValues
->erase( pos
);
674 lcl_notifyMapDataListeners_nothrow( m_aData
);
676 return previousValue
;
679 //--------------------------------------------------------------------
680 Type SAL_CALL
EnumerableMap::getElementType() throw (RuntimeException
)
682 return ::cppu::UnoType
< Pair
< Any
, Any
> >::get();
685 //--------------------------------------------------------------------
686 ::sal_Bool SAL_CALL
EnumerableMap::hasElements() throw (RuntimeException
)
688 ComponentMethodGuard
aGuard( *this );
689 return m_aData
.m_pValues
->empty();
692 //--------------------------------------------------------------------
693 ::rtl::OUString SAL_CALL
EnumerableMap::getImplementationName( ) throw (RuntimeException
)
695 return getImplementationName_static();
698 //--------------------------------------------------------------------
699 ::sal_Bool SAL_CALL
EnumerableMap::supportsService( const ::rtl::OUString
& _serviceName
) throw (RuntimeException
)
701 Sequence
< ::rtl::OUString
> aServices( getSupportedServiceNames() );
702 for ( sal_Int32 i
=0; i
<aServices
.getLength(); ++i
)
703 if ( _serviceName
== aServices
[i
] )
708 //--------------------------------------------------------------------
709 Sequence
< ::rtl::OUString
> SAL_CALL
EnumerableMap::getSupportedServiceNames( ) throw (RuntimeException
)
711 return getSupportedServiceNames_static();
714 //--------------------------------------------------------------------
715 ::rtl::OUString SAL_CALL
EnumerableMap::getImplementationName_static( )
717 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.comphelper.EnumerableMap" ) );
720 //--------------------------------------------------------------------
721 Sequence
< ::rtl::OUString
> SAL_CALL
EnumerableMap::getSupportedServiceNames_static( )
723 Sequence
< ::rtl::OUString
> aServiceNames(1);
724 aServiceNames
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.container.EnumerableMap" ) );
725 return aServiceNames
;
728 //--------------------------------------------------------------------
729 Reference
< XInterface
> SAL_CALL
EnumerableMap::Create( SAL_UNUSED_PARAMETER
const Reference
< XComponentContext
>& )
731 return *new EnumerableMap
;
734 //====================================================================
736 //====================================================================
737 //--------------------------------------------------------------------
738 ::sal_Bool
MapEnumerator::hasMoreElements()
741 throw DisposedException( ::rtl::OUString(), m_rParent
);
742 return m_mapPos
!= m_rMapData
.m_pValues
->end();
745 //--------------------------------------------------------------------
746 Any
MapEnumerator::nextElement()
749 throw DisposedException( ::rtl::OUString(), m_rParent
);
750 if ( m_mapPos
== m_rMapData
.m_pValues
->end() )
751 throw NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No more elements." ) ), m_rParent
);
756 case eKeys
: aNextElement
= m_mapPos
->first
; break;
757 case eValues
: aNextElement
= m_mapPos
->second
; break;
758 case eBoth
: aNextElement
<<= Pair
< Any
, Any
>( m_mapPos
->first
, m_mapPos
->second
); break;
764 //--------------------------------------------------------------------
765 void MapEnumerator::mapModified()
770 //====================================================================
771 //= MapEnumeration - implementation
772 //====================================================================
773 //--------------------------------------------------------------------
774 ::sal_Bool SAL_CALL
MapEnumeration::hasMoreElements( ) throw (RuntimeException
)
776 ComponentMethodGuard
aGuard( *this );
777 return m_aEnumerator
.hasMoreElements();
780 //--------------------------------------------------------------------
781 Any SAL_CALL
MapEnumeration::nextElement( ) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
)
783 ComponentMethodGuard
aGuard( *this );
784 return m_aEnumerator
.nextElement();
787 //........................................................................
788 } // namespace comphelper
789 //........................................................................
791 void createRegistryInfo_Map()
793 ::comphelper::module::OAutoRegistration
< ::comphelper::EnumerableMap
> aAutoRegistration
;
796 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */