1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
30 #include <comphelper/enumhelper.hxx>
31 #include <com/sun/star/lang/XComponent.hpp>
32 
33 //.........................................................................
34 namespace comphelper
35 {
36 //.........................................................................
37 
38 //==================================================================
39 //= OEnumerationByName
40 //==================================================================
41 //------------------------------------------------------------------------------
42 OEnumerationByName::OEnumerationByName(const staruno::Reference<starcontainer::XNameAccess>& _rxAccess)
43     :m_aNames(_rxAccess->getElementNames())
44     ,m_nPos(0)
45     ,m_xAccess(_rxAccess)
46     ,m_bListening(sal_False)
47 {
48     impl_startDisposeListening();
49 }
50 
51 //------------------------------------------------------------------------------
52 OEnumerationByName::OEnumerationByName(const staruno::Reference<starcontainer::XNameAccess>& _rxAccess,
53                                        const staruno::Sequence< ::rtl::OUString >&           _aNames  )
54     :m_aNames(_aNames)
55     ,m_nPos(0)
56     ,m_xAccess(_rxAccess)
57     ,m_bListening(sal_False)
58 {
59     impl_startDisposeListening();
60 }
61 
62 //------------------------------------------------------------------------------
63 OEnumerationByName::~OEnumerationByName()
64 {
65     impl_stopDisposeListening();
66 }
67 
68 //------------------------------------------------------------------------------
69 sal_Bool SAL_CALL OEnumerationByName::hasMoreElements(  ) throw(staruno::RuntimeException)
70 {
71     ::osl::ResettableMutexGuard aLock(m_aLock);
72 
73 	if (m_xAccess.is() && m_aNames.getLength() > m_nPos)
74         return sal_True;
75 
76     if (m_xAccess.is())
77     {
78         impl_stopDisposeListening();
79         m_xAccess.clear();
80     }
81 
82     return sal_False;
83 }
84 
85 //------------------------------------------------------------------------------
86 staruno::Any SAL_CALL OEnumerationByName::nextElement(  )
87 		throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException)
88 {
89     ::osl::ResettableMutexGuard aLock(m_aLock);
90 
91 	staruno::Any aRes;
92 	if (m_xAccess.is() && m_nPos < m_aNames.getLength())
93 		aRes = m_xAccess->getByName(m_aNames.getConstArray()[m_nPos++]);
94 
95 	if (m_xAccess.is() && m_nPos >= m_aNames.getLength())
96     {
97         impl_stopDisposeListening();
98         m_xAccess.clear();
99     }
100 
101 	if (!aRes.hasValue())		// es gibt kein Element mehr
102 		throw starcontainer::NoSuchElementException();
103 
104 	return aRes;
105 }
106 
107 //------------------------------------------------------------------------------
108 void SAL_CALL OEnumerationByName::disposing(const starlang::EventObject& aEvent)
109         throw(staruno::RuntimeException)
110 {
111     ::osl::ResettableMutexGuard aLock(m_aLock);
112 
113     if (aEvent.Source == m_xAccess)
114         m_xAccess.clear();
115 }
116 
117 //------------------------------------------------------------------------------
118 void OEnumerationByName::impl_startDisposeListening()
119 {
120     ::osl::ResettableMutexGuard aLock(m_aLock);
121 
122     if (m_bListening)
123         return;
124 
125     ++m_refCount;
126     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
127     if (xDisposable.is())
128     {
129         xDisposable->addEventListener(this);
130         m_bListening = sal_True;
131     }
132     --m_refCount;
133 }
134 
135 //------------------------------------------------------------------------------
136 void OEnumerationByName::impl_stopDisposeListening()
137 {
138     ::osl::ResettableMutexGuard aLock(m_aLock);
139 
140     if (!m_bListening)
141         return;
142 
143     ++m_refCount;
144     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
145     if (xDisposable.is())
146     {
147         xDisposable->removeEventListener(this);
148         m_bListening = sal_False;
149     }
150     --m_refCount;
151 }
152 
153 //==================================================================
154 //= OEnumerationByIndex
155 //==================================================================
156 //------------------------------------------------------------------------------
157 OEnumerationByIndex::OEnumerationByIndex(const staruno::Reference< starcontainer::XIndexAccess >& _rxAccess)
158     :m_nPos(0)
159     ,m_xAccess(_rxAccess)
160     ,m_bListening(sal_False)
161 {
162     impl_startDisposeListening();
163 }
164 
165 //------------------------------------------------------------------------------
166 OEnumerationByIndex::~OEnumerationByIndex()
167 {
168     impl_stopDisposeListening();
169 }
170 
171 //------------------------------------------------------------------------------
172 sal_Bool SAL_CALL OEnumerationByIndex::hasMoreElements(  ) throw(staruno::RuntimeException)
173 {
174     ::osl::ResettableMutexGuard aLock(m_aLock);
175 
176 	if (m_xAccess.is() && m_xAccess->getCount() > m_nPos)
177         return sal_True;
178 
179     if (m_xAccess.is())
180     {
181         impl_stopDisposeListening();
182         m_xAccess.clear();
183     }
184 
185     return sal_False;
186 }
187 
188 //------------------------------------------------------------------------------
189 staruno::Any SAL_CALL OEnumerationByIndex::nextElement(  )
190 		throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException)
191 {
192     ::osl::ResettableMutexGuard aLock(m_aLock);
193 
194 	staruno::Any aRes;
195 	if (m_xAccess.is())
196 	{
197 		aRes = m_xAccess->getByIndex(m_nPos++);
198 		if (m_nPos >= m_xAccess->getCount())
199         {
200             impl_stopDisposeListening();
201             m_xAccess.clear();
202         }
203 	}
204 
205 	if (!aRes.hasValue())		// es gibt kein Element mehr
206 		throw starcontainer::NoSuchElementException();
207 	return aRes;
208 }
209 
210 //------------------------------------------------------------------------------
211 void SAL_CALL OEnumerationByIndex::disposing(const starlang::EventObject& aEvent)
212         throw(staruno::RuntimeException)
213 {
214     ::osl::ResettableMutexGuard aLock(m_aLock);
215 
216     if (aEvent.Source == m_xAccess)
217         m_xAccess.clear();
218 }
219 
220 //------------------------------------------------------------------------------
221 void OEnumerationByIndex::impl_startDisposeListening()
222 {
223     ::osl::ResettableMutexGuard aLock(m_aLock);
224 
225     if (m_bListening)
226         return;
227 
228     ++m_refCount;
229     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
230     if (xDisposable.is())
231     {
232         xDisposable->addEventListener(this);
233         m_bListening = sal_True;
234     }
235     --m_refCount;
236 }
237 
238 //------------------------------------------------------------------------------
239 void OEnumerationByIndex::impl_stopDisposeListening()
240 {
241     ::osl::ResettableMutexGuard aLock(m_aLock);
242 
243     if (!m_bListening)
244         return;
245 
246     ++m_refCount;
247     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
248     if (xDisposable.is())
249     {
250         xDisposable->removeEventListener(this);
251         m_bListening = sal_False;
252     }
253     --m_refCount;
254 }
255 
256 //==================================================================
257 //= OAnyEnumeration
258 //==================================================================
259 
260 //------------------------------------------------------------------------------
261 OAnyEnumeration::OAnyEnumeration(const staruno::Sequence< staruno::Any >& lItems)
262     :m_nPos(0)
263     ,m_lItems(lItems)
264 {
265 }
266 
267 //------------------------------------------------------------------------------
268 OAnyEnumeration::~OAnyEnumeration()
269 {
270 }
271 
272 //------------------------------------------------------------------------------
273 sal_Bool SAL_CALL OAnyEnumeration::hasMoreElements(  ) throw(staruno::RuntimeException)
274 {
275     ::osl::ResettableMutexGuard aLock(m_aLock);
276 
277 	return (m_lItems.getLength() > m_nPos);
278 }
279 
280 //------------------------------------------------------------------------------
281 staruno::Any SAL_CALL OAnyEnumeration::nextElement(  )
282 		throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException)
283 {
284 	if ( ! hasMoreElements())
285 		throw starcontainer::NoSuchElementException();
286 
287     ::osl::ResettableMutexGuard aLock(m_aLock);
288     sal_Int32 nPos = m_nPos;
289     ++m_nPos;
290     return m_lItems[nPos];
291 }
292 
293 //.........................................................................
294 }	// namespace comphelper
295 //.........................................................................
296 
297 
298