1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: collection.hxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #ifndef _COLLECTION_HXX
32 #define _COLLECTION_HXX
34 #include "enumeration.hxx"
36 #include <cppuhelper/implbase3.hxx>
37 #include <com/sun/star/container/ElementExistException.hpp>
38 #include <com/sun/star/container/NoSuchElementException.hpp>
39 #include <com/sun/star/container/XEnumeration.hpp>
40 #include <com/sun/star/container/XIndexReplace.hpp>
41 #include <com/sun/star/container/XSet.hpp>
42 #include <com/sun/star/container/XContainer.hpp>
43 #include <com/sun/star/container/XContainerListener.hpp>
44 #include <com/sun/star/lang/IllegalArgumentException.hpp>
45 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
46 #include <com/sun/star/lang/WrappedTargetException.hpp>
47 #include <com/sun/star/uno/Any.hxx>
48 #include <com/sun/star/uno/Reference.hxx>
49 #include <com/sun/star/uno/RuntimeException.hpp>
50 #include <com/sun/star/uno/Type.hxx>
55 typedef cppu::WeakImplHelper3
<
56 com::sun::star::container::XIndexReplace
,
57 com::sun::star::container::XSet
,
58 com::sun::star::container::XContainer
>
61 template<class ELEMENT_TYPE
>
62 class Collection
: public Collection_t
65 typedef ELEMENT_TYPE T
;
66 typedef com::sun::star::uno::Reference
<com::sun::star::container::XContainerListener
> XContainerListener_t
;
67 typedef std::vector
<XContainerListener_t
> Listeners_t
;
70 std::vector
<T
> maItems
;
71 Listeners_t maListeners
;
76 virtual ~Collection() {}
78 const T
& getItem( sal_Int32 n
) const
80 OSL_ENSURE( isValidIndex(n
), "invalid index" );
81 OSL_ENSURE( isValid( maItems
[n
] ), "invalid item found" );
85 void setItem( sal_Int32 n
, const T
& t
)
87 OSL_ENSURE( isValidIndex(n
), "invalid index" );
88 OSL_ENSURE( isValid ( t
), "invalid item" );
90 T
& aRef
= maItems
[ n
];
91 _elementReplaced( n
, t
);
97 bool hasItem( const T
& t
) const
99 return maItems
.end() != std::find( maItems
.begin(), maItems
.end(), t
);
102 sal_Int32
addItem( const T
& t
)
104 OSL_ENSURE( !hasItem( t
), "item to be added already present" );
105 OSL_ENSURE( isValid( t
), "invalid item" );
107 maItems
.push_back( t
);
109 _elementInserted( maItems
.size() - 1 );
110 return ( maItems
.size() - 1 );
113 void removeItem( const T
& t
)
115 OSL_ENSURE( hasItem( t
), "item to be removed not present" );
116 OSL_ENSURE( isValid( t
), "an invalid item, funny that!" );
118 _elementRemoved( t
);
120 maItems
.erase( std::find( maItems
.begin(), maItems
.end(), t
) );
123 bool hasItems() const
125 return maItems
.size() != 0;
128 sal_Int32
countItems() const
130 return static_cast<sal_Int32
>( maItems
.size() );
133 bool isValidIndex( sal_Int32 n
) const
135 return n
>= 0 && n
< static_cast<sal_Int32
>( maItems
.size() );
139 // the following method may be overriden by sub-classes for
140 // customized behaviour
142 /// called before insertion to determine whether item is valid
143 virtual bool isValid( const T
& ) const { return true; }
148 // the following methods may be overriden by sub-classes for
149 // customized behaviour
151 /// called after item has been inserted into the collection
152 virtual void _insert( const T
& ) { }
154 /// called before item is removed from the collection
155 virtual void _remove( const T
& ) { }
159 typedef com::sun::star::uno::Type Type_t
;
160 typedef com::sun::star::uno::Any Any_t
;
161 typedef com::sun::star::uno::RuntimeException RuntimeException_t
;
162 typedef com::sun::star::lang::IllegalArgumentException IllegalArgumentException_t
;
163 typedef com::sun::star::container::NoSuchElementException NoSuchElementException_t
;
164 typedef com::sun::star::lang::IndexOutOfBoundsException IndexOutOfBoundsException_t
;
165 typedef com::sun::star::uno::Reference
<com::sun::star::container::XEnumeration
> XEnumeration_t
;
166 typedef com::sun::star::lang::WrappedTargetException WrappedTargetException_t
;
167 typedef com::sun::star::container::ElementExistException ElementExistException_t
;
171 virtual Type_t SAL_CALL
getElementType()
172 throw( RuntimeException_t
)
174 return getCppuType( static_cast<T
*>( NULL
) );
177 virtual sal_Bool SAL_CALL
hasElements()
178 throw( RuntimeException_t
)
183 // XIndexAccess : XElementAccess
184 virtual sal_Int32 SAL_CALL
getCount()
185 throw( RuntimeException_t
)
190 virtual Any_t SAL_CALL
getByIndex( sal_Int32 nIndex
)
191 throw( IndexOutOfBoundsException_t
,
192 WrappedTargetException_t
,
195 if( isValidIndex( nIndex
) )
196 return com::sun::star::uno::makeAny( getItem( nIndex
) );
198 throw IndexOutOfBoundsException_t();
201 // XIndexReplace : XIndexAccess
202 virtual void SAL_CALL
replaceByIndex( sal_Int32 nIndex
,
203 const Any_t
& aElement
)
204 throw( IllegalArgumentException_t
,
205 IndexOutOfBoundsException_t
,
206 WrappedTargetException_t
,
210 if( isValidIndex( nIndex
) )
211 if( ( aElement
>>= t
) && isValid( t
) )
212 setItem( nIndex
, t
);
214 throw IllegalArgumentException_t();
216 throw IndexOutOfBoundsException_t();
219 // XEnumerationAccess : XElementAccess
220 virtual XEnumeration_t SAL_CALL
createEnumeration()
221 throw( RuntimeException_t
)
223 return new Enumeration( this );
227 // XSet : XEnumerationAccess
228 virtual sal_Bool SAL_CALL
has( const Any_t
& aElement
)
229 throw( RuntimeException_t
)
232 return ( aElement
>>= t
) ? hasItem( t
) : sal_False
;
235 virtual void SAL_CALL
insert( const Any_t
& aElement
)
236 throw( IllegalArgumentException_t
,
237 ElementExistException_t
,
241 if( ( aElement
>>= t
) && isValid( t
) )
245 throw ElementExistException_t();
247 throw IllegalArgumentException_t();
250 virtual void SAL_CALL
remove( const Any_t
& aElement
)
251 throw( IllegalArgumentException_t
,
252 NoSuchElementException_t
,
260 throw NoSuchElementException_t();
262 throw IllegalArgumentException_t();
267 virtual void SAL_CALL
addContainerListener(
268 const XContainerListener_t
& xListener
)
269 throw( RuntimeException_t
)
271 OSL_ENSURE( xListener
.is(), "need listener!" );
272 if( std::find( maListeners
.begin(), maListeners
.end(), xListener
)
273 == maListeners
.end() )
274 maListeners
.push_back( xListener
);
277 virtual void SAL_CALL
removeContainerListener(
278 const XContainerListener_t
& xListener
)
279 throw( RuntimeException_t
)
281 OSL_ENSURE( xListener
.is(), "need listener!" );
282 Listeners_t::iterator aIter
=
283 std::find( maListeners
.begin(), maListeners
.end(), xListener
);
284 if( aIter
!= maListeners
.end() )
285 maListeners
.erase( aIter
);
291 void _elementInserted( sal_Int32 nPos
)
293 OSL_ENSURE( isValidIndex(nPos
), "invalid index" );
294 com::sun::star::container::ContainerEvent
aEvent(
295 static_cast<com::sun::star::container::XIndexReplace
*>( this ),
296 com::sun::star::uno::makeAny( nPos
),
297 com::sun::star::uno::makeAny( getItem( nPos
) ),
298 com::sun::star::uno::Any() );
299 for( Listeners_t::iterator aIter
= maListeners
.begin();
300 aIter
!= maListeners
.end();
303 (*aIter
)->elementInserted( aEvent
);
307 void _elementRemoved( const T
& aOld
)
309 com::sun::star::container::ContainerEvent
aEvent(
310 static_cast<com::sun::star::container::XIndexReplace
*>( this ),
311 com::sun::star::uno::Any(),
312 com::sun::star::uno::makeAny( aOld
),
313 com::sun::star::uno::Any() );
314 for( Listeners_t::iterator aIter
= maListeners
.begin();
315 aIter
!= maListeners
.end();
318 (*aIter
)->elementRemoved( aEvent
);
322 void _elementReplaced( const sal_Int32 nPos
, const T
& aNew
)
324 OSL_ENSURE( isValidIndex(nPos
), "invalid index" );
325 com::sun::star::container::ContainerEvent
aEvent(
326 static_cast<com::sun::star::container::XIndexReplace
*>( this ),
327 com::sun::star::uno::makeAny( nPos
),
328 com::sun::star::uno::makeAny( getItem( nPos
) ),
329 com::sun::star::uno::makeAny( aNew
) );
330 for( Listeners_t::iterator aIter
= maListeners
.begin();
331 aIter
!= maListeners
.end();
334 (*aIter
)->elementReplaced( aEvent
);