1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_comphelper.hxx"
26 #include <comphelper/enumhelper.hxx>
27 #include <com/sun/star/lang/XComponent.hpp>
28 
29 //.........................................................................
30 namespace comphelper
31 {
32 //.........................................................................
33 
34 //==================================================================
35 //= OEnumerationByName
36 //==================================================================
37 //------------------------------------------------------------------------------
38 OEnumerationByName::OEnumerationByName(const staruno::Reference<starcontainer::XNameAccess>& _rxAccess)
39     :m_aNames(_rxAccess->getElementNames())
40     ,m_nPos(0)
41     ,m_xAccess(_rxAccess)
42     ,m_bListening(sal_False)
43 {
44     impl_startDisposeListening();
45 }
46 
47 //------------------------------------------------------------------------------
48 OEnumerationByName::OEnumerationByName(const staruno::Reference<starcontainer::XNameAccess>& _rxAccess,
49                                        const staruno::Sequence< ::rtl::OUString >&           _aNames  )
50     :m_aNames(_aNames)
51     ,m_nPos(0)
52     ,m_xAccess(_rxAccess)
53     ,m_bListening(sal_False)
54 {
55     impl_startDisposeListening();
56 }
57 
58 //------------------------------------------------------------------------------
59 OEnumerationByName::~OEnumerationByName()
60 {
61     impl_stopDisposeListening();
62 }
63 
64 //------------------------------------------------------------------------------
65 sal_Bool SAL_CALL OEnumerationByName::hasMoreElements(  ) throw(staruno::RuntimeException)
66 {
67     ::osl::ResettableMutexGuard aLock(m_aLock);
68 
69 	if (m_xAccess.is() && m_aNames.getLength() > m_nPos)
70         return sal_True;
71 
72     if (m_xAccess.is())
73     {
74         impl_stopDisposeListening();
75         m_xAccess.clear();
76     }
77 
78     return sal_False;
79 }
80 
81 //------------------------------------------------------------------------------
82 staruno::Any SAL_CALL OEnumerationByName::nextElement(  )
83 		throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException)
84 {
85     ::osl::ResettableMutexGuard aLock(m_aLock);
86 
87 	staruno::Any aRes;
88 	if (m_xAccess.is() && m_nPos < m_aNames.getLength())
89 		aRes = m_xAccess->getByName(m_aNames.getConstArray()[m_nPos++]);
90 
91 	if (m_xAccess.is() && m_nPos >= m_aNames.getLength())
92     {
93         impl_stopDisposeListening();
94         m_xAccess.clear();
95     }
96 
97 	if (!aRes.hasValue())		// es gibt kein Element mehr
98 		throw starcontainer::NoSuchElementException();
99 
100 	return aRes;
101 }
102 
103 //------------------------------------------------------------------------------
104 void SAL_CALL OEnumerationByName::disposing(const starlang::EventObject& aEvent)
105         throw(staruno::RuntimeException)
106 {
107     ::osl::ResettableMutexGuard aLock(m_aLock);
108 
109     if (aEvent.Source == m_xAccess)
110         m_xAccess.clear();
111 }
112 
113 //------------------------------------------------------------------------------
114 void OEnumerationByName::impl_startDisposeListening()
115 {
116     ::osl::ResettableMutexGuard aLock(m_aLock);
117 
118     if (m_bListening)
119         return;
120 
121     ++m_refCount;
122     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
123     if (xDisposable.is())
124     {
125         xDisposable->addEventListener(this);
126         m_bListening = sal_True;
127     }
128     --m_refCount;
129 }
130 
131 //------------------------------------------------------------------------------
132 void OEnumerationByName::impl_stopDisposeListening()
133 {
134     ::osl::ResettableMutexGuard aLock(m_aLock);
135 
136     if (!m_bListening)
137         return;
138 
139     ++m_refCount;
140     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
141     if (xDisposable.is())
142     {
143         xDisposable->removeEventListener(this);
144         m_bListening = sal_False;
145     }
146     --m_refCount;
147 }
148 
149 //==================================================================
150 //= OEnumerationByIndex
151 //==================================================================
152 //------------------------------------------------------------------------------
153 OEnumerationByIndex::OEnumerationByIndex(const staruno::Reference< starcontainer::XIndexAccess >& _rxAccess)
154     :m_nPos(0)
155     ,m_xAccess(_rxAccess)
156     ,m_bListening(sal_False)
157 {
158     impl_startDisposeListening();
159 }
160 
161 //------------------------------------------------------------------------------
162 OEnumerationByIndex::~OEnumerationByIndex()
163 {
164     impl_stopDisposeListening();
165 }
166 
167 //------------------------------------------------------------------------------
168 sal_Bool SAL_CALL OEnumerationByIndex::hasMoreElements(  ) throw(staruno::RuntimeException)
169 {
170     ::osl::ResettableMutexGuard aLock(m_aLock);
171 
172 	if (m_xAccess.is() && m_xAccess->getCount() > m_nPos)
173         return sal_True;
174 
175     if (m_xAccess.is())
176     {
177         impl_stopDisposeListening();
178         m_xAccess.clear();
179     }
180 
181     return sal_False;
182 }
183 
184 //------------------------------------------------------------------------------
185 staruno::Any SAL_CALL OEnumerationByIndex::nextElement(  )
186 		throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException)
187 {
188     ::osl::ResettableMutexGuard aLock(m_aLock);
189 
190 	staruno::Any aRes;
191     if (m_xAccess.is() && m_nPos < m_xAccess->getCount())
192         aRes = m_xAccess->getByIndex(m_nPos++);
193 
194     if (m_xAccess.is() && m_nPos >= m_xAccess->getCount())
195     {
196         impl_stopDisposeListening();
197         m_xAccess.clear();
198     }
199 
200 	if (!aRes.hasValue())		// es gibt kein Element mehr
201 		throw starcontainer::NoSuchElementException();
202 	return aRes;
203 }
204 
205 //------------------------------------------------------------------------------
206 void SAL_CALL OEnumerationByIndex::disposing(const starlang::EventObject& aEvent)
207         throw(staruno::RuntimeException)
208 {
209     ::osl::ResettableMutexGuard aLock(m_aLock);
210 
211     if (aEvent.Source == m_xAccess)
212         m_xAccess.clear();
213 }
214 
215 //------------------------------------------------------------------------------
216 void OEnumerationByIndex::impl_startDisposeListening()
217 {
218     ::osl::ResettableMutexGuard aLock(m_aLock);
219 
220     if (m_bListening)
221         return;
222 
223     ++m_refCount;
224     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
225     if (xDisposable.is())
226     {
227         xDisposable->addEventListener(this);
228         m_bListening = sal_True;
229     }
230     --m_refCount;
231 }
232 
233 //------------------------------------------------------------------------------
234 void OEnumerationByIndex::impl_stopDisposeListening()
235 {
236     ::osl::ResettableMutexGuard aLock(m_aLock);
237 
238     if (!m_bListening)
239         return;
240 
241     ++m_refCount;
242     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
243     if (xDisposable.is())
244     {
245         xDisposable->removeEventListener(this);
246         m_bListening = sal_False;
247     }
248     --m_refCount;
249 }
250 
251 //==================================================================
252 //= OAnyEnumeration
253 //==================================================================
254 
255 //------------------------------------------------------------------------------
256 OAnyEnumeration::OAnyEnumeration(const staruno::Sequence< staruno::Any >& lItems)
257     :m_nPos(0)
258     ,m_lItems(lItems)
259 {
260 }
261 
262 //------------------------------------------------------------------------------
263 OAnyEnumeration::~OAnyEnumeration()
264 {
265 }
266 
267 //------------------------------------------------------------------------------
268 sal_Bool SAL_CALL OAnyEnumeration::hasMoreElements(  ) throw(staruno::RuntimeException)
269 {
270     ::osl::ResettableMutexGuard aLock(m_aLock);
271 
272 	return (m_lItems.getLength() > m_nPos);
273 }
274 
275 //------------------------------------------------------------------------------
276 staruno::Any SAL_CALL OAnyEnumeration::nextElement(  )
277 		throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException)
278 {
279 	if ( ! hasMoreElements())
280 		throw starcontainer::NoSuchElementException();
281 
282     ::osl::ResettableMutexGuard aLock(m_aLock);
283     sal_Int32 nPos = m_nPos;
284     ++m_nPos;
285     return m_lItems[nPos];
286 }
287 
288 //.........................................................................
289 }	// namespace comphelper
290 //.........................................................................
291 
292 
293