View Javadoc
1   /*
2     (C) Copyright IBM Corp. 2007, 2009
3   
4     THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
5     ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
6     CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
7   
8     You can obtain a current copy of the Eclipse Public License from
9     http://www.opensource.org/licenses/eclipse-1.0.php
10  
11    @author : Endre Bak, IBM, ebak@de.ibm.com
12   * 
13   * Change History
14   * Flag       Date        Prog         Description
15   *------------------------------------------------------------------------------- 
16   * 1804402    2007-09-28  ebak         IPv6 ready SLP
17   * 1892103    2008-02-12  ebak         SLP improvements
18   * 1949918    2008-04-08  raman_arora  Malformed service URL crashes SLP discovery
19   * 2003590    2008-06-30  blaschke-oss Change licensing from CPL to EPL
20   * 2204488 	  2008-10-28  raman_arora  Fix code to remove compiler warnings
21   * 2524131    2009-01-21  raman_arora  Upgrade client to JDK 1.5 (Phase 1)
22   * 2531371    2009-02-10  raman_arora  Upgrade client to JDK 1.5 (Phase 2) 
23   */
24  
25  package org.metricshub.wbem.sblim.slp.internal.ua;
26  
27  /*-
28   * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
29   * WBEM Java Client
30   * ჻჻჻჻჻჻
31   * Copyright 2023 - 2025 MetricsHub
32   * ჻჻჻჻჻჻
33   * Licensed under the Apache License, Version 2.0 (the "License");
34   * you may not use this file except in compliance with the License.
35   * You may obtain a copy of the License at
36   *
37   *      http://www.apache.org/licenses/LICENSE-2.0
38   *
39   * Unless required by applicable law or agreed to in writing, software
40   * distributed under the License is distributed on an "AS IS" BASIS,
41   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42   * See the License for the specific language governing permissions and
43   * limitations under the License.
44   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
45   */
46  
47  import java.util.ArrayList;
48  import java.util.Iterator;
49  import java.util.LinkedHashSet;
50  import java.util.NoSuchElementException;
51  import org.metricshub.wbem.sblim.slp.internal.TRC;
52  import org.metricshub.wbem.sblim.slp.internal.msg.ReplyMessage;
53  
54  /**
55   * ResultTable
56   *
57   */
58  public class ResultTable implements Iterator<Object> {
59  	private ArrayList<DatagramRequester> iRequesters = new ArrayList<DatagramRequester>();
60  
61  	private ArrayList<Exception> iExceptions = new ArrayList<Exception>();
62  
63  	/*
64  	 * iInSet contains the results which are not read out. iOutSet contains the
65  	 * results which are read out.
66  	 */
67  	private LinkedHashSet<Object> iInSet = new LinkedHashSet<Object>();
68  
69  	private LinkedHashSet<Object> iOutSet = new LinkedHashSet<Object>();
70  
71  	/**
72  	 * ResultTable has to know which Requesters provide results. Requester have
73  	 * to be registered before hasNext() is called.
74  	 *
75  	 * @see #unregisterRequester(DatagramRequester)
76  	 * @param pReq
77  	 */
78  	public synchronized void registerRequester(DatagramRequester pReq) {
79  		for (int i = 0; i < this.iRequesters.size(); i++) if (pReq == this.iRequesters.get(i)) return;
80  		this.iRequesters.add(pReq);
81  	}
82  
83  	/**
84  	 * If the Requester's sequence is completed, Requester has to be
85  	 * unregistered otherwise hasNext() will block.
86  	 *
87  	 * @param pReq
88  	 */
89  	public synchronized void unregisterRequester(DatagramRequester pReq) {
90  		for (int i = 0; i < this.iRequesters.size(); i++) {
91  			if (pReq == this.iRequesters.get(i)) {
92  				this.iRequesters.remove(i);
93  				if (this.iRequesters.size() == 0) wakeUp();
94  				return;
95  			}
96  		}
97  	}
98  
99  	/**
100 	 * addResults
101 	 *
102 	 * @param pReplyMsg
103 	 */
104 	public void addResults(ReplyMessage pReplyMsg) {
105 		addResults(pReplyMsg.getResultIterator());
106 	}
107 
108 	/**
109 	 * addResults
110 	 *
111 	 * @param pResItr
112 	 */
113 	public synchronized void addResults(Iterator<?> pResItr) {
114 		if (pResItr == null) return;
115 		while (pResItr.hasNext()) addResult(pResItr.next());
116 		// waking up hasNext()
117 		if (this.iInSet.size() > 0) wakeUp();
118 	}
119 
120 	/**
121 	 * addExceptions
122 	 *
123 	 * @param pReplyMsg
124 	 */
125 	public synchronized void addExceptions(ReplyMessage pReplyMsg) {
126 		addExceptions(pReplyMsg.getExceptionIterator());
127 	}
128 
129 	/**
130 	 * addExceptions
131 	 *
132 	 * @param pExceptionItr
133 	 */
134 	public synchronized void addExceptions(Iterator<?> pExceptionItr) {
135 		if (pExceptionItr == null) return;
136 		while (pExceptionItr.hasNext()) addException((Exception) pExceptionItr.next());
137 	}
138 
139 	/**
140 	 * addException
141 	 *
142 	 * @param pE
143 	 */
144 	public synchronized void addException(Exception pE) {
145 		this.iExceptions.add(pE);
146 		if (this.iExceptions.size() > 0) wakeUp();
147 	}
148 
149 	/**
150 	 * getTotalResponses
151 	 *
152 	 * @return int
153 	 */
154 	public synchronized int getTotalResponses() {
155 		return this.iOutSet.size() + this.iInSet.size();
156 	}
157 
158 	/**
159 	 * @see java.util.Iterator#hasNext()
160 	 * @return true if there are results or exceptions to read
161 	 */
162 	public synchronized boolean hasNext() {
163 		if (hasData()) return true;
164 		// no more requester, no chance for result
165 		if (this.iRequesters.size() == 0) return false;
166 		/*
167 		 * wait wake up if iInSet is extended or all Requesters are unregistered
168 		 */
169 		try {
170 			wait();
171 		} catch (InterruptedException e) {
172 			TRC.error(e);
173 		}
174 		return hasData();
175 	}
176 
177 	/**
178 	 * @see java.util.Iterator#next()
179 	 * @return a result or an Exception
180 	 */
181 	public synchronized Object next() throws NoSuchElementException {
182 		Iterator<Object> itr = this.iInSet.iterator();
183 		Object res = itr.next();
184 		this.iInSet.remove(res);
185 		this.iOutSet.add(res);
186 		return res;
187 	}
188 
189 	/**
190 	 * @return next element in Exception table
191 	 * @throws NoSuchElementException
192 	 */
193 	public Object nextException() throws NoSuchElementException {
194 		Iterator<Exception> itr = this.iExceptions.iterator();
195 		Object res = itr.next();
196 		this.iExceptions.remove(res);
197 		return res;
198 	}
199 
200 	/**
201 	 * @return next element in Exception table
202 	 */
203 	public boolean hasMoreExceptions() {
204 		return this.iExceptions.size() > 0;
205 	}
206 
207 	public void remove() {
208 		throw new UnsupportedOperationException();
209 	}
210 
211 	private void addResult(Object pResult) {
212 		if (this.iOutSet.contains(pResult) || this.iInSet.contains(pResult)) return;
213 		this.iInSet.add(pResult);
214 	}
215 
216 	private void wakeUp() {
217 		try {
218 			notifyAll();
219 		} catch (IllegalMonitorStateException e) {
220 			TRC.error(e);
221 		}
222 	}
223 
224 	private boolean hasData() {
225 		return this.iInSet.size() > 0;
226 	}
227 }