1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.metricshub.wbem.sblim.slp.internal.sa;
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 import java.io.IOException;
46 import java.net.UnknownHostException;
47 import java.util.ArrayList;
48 import java.util.HashMap;
49 import java.util.HashSet;
50 import java.util.Iterator;
51 import java.util.List;
52 import org.metricshub.wbem.sblim.slp.ServiceLocationAttribute;
53 import org.metricshub.wbem.sblim.slp.ServiceType;
54 import org.metricshub.wbem.sblim.slp.ServiceURL;
55 import org.metricshub.wbem.sblim.slp.internal.IPv6MulticastAddressFactory;
56 import org.metricshub.wbem.sblim.slp.internal.Net;
57 import org.metricshub.wbem.sblim.slp.internal.SLPConfig;
58 import org.metricshub.wbem.sblim.slp.internal.SLPDefaults;
59 import org.metricshub.wbem.sblim.slp.internal.TRC;
60
61
62
63
64
65 public class ServiceTable {
66 DatagramThread iDgramThread;
67
68 private boolean iUseV6 = Net.hasIPv6() && SLPConfig.getGlobalCfg().useIPv6();
69
70 class AddressHashTable {
71
72 class Counter {
73
74
75
76 public int iValue = 1;
77 }
78
79
80
81
82 private HashMap<Integer, Counter> iMap = new HashMap<Integer, Counter>();
83
84
85
86
87
88
89
90
91 public void register(ServiceType pType) throws UnknownHostException, IOException {
92 Integer hash = Integer.valueOf(IPv6MulticastAddressFactory.getSrvTypeHash(pType));
93 TRC.debug("srvType:" + pType + ", hash:" + hash);
94 Counter cntr = this.iMap.get(hash);
95 if (cntr == null) {
96 cntr = new Counter();
97 this.iMap.put(hash, cntr);
98 ServiceTable.this.iDgramThread.joinGroup(
99 IPv6MulticastAddressFactory.get(SLPDefaults.IPV6_MULTICAST_SCOPE, hash.intValue())
100 );
101 } else {
102 ++cntr.iValue;
103 }
104 }
105
106
107
108
109
110
111
112
113 public void unregister(ServiceType pType) throws UnknownHostException, IOException {
114 Integer hash = Integer.valueOf(IPv6MulticastAddressFactory.getSrvTypeHash(pType));
115 Counter cntr = this.iMap.get(hash);
116 if (cntr == null) return;
117 if (cntr.iValue <= 1) {
118 this.iMap.remove(hash);
119 ServiceTable.this.iDgramThread.leaveGroup(
120 IPv6MulticastAddressFactory.get(SLPDefaults.IPV6_MULTICAST_SCOPE, hash.intValue())
121 );
122 } else {
123 --cntr.iValue;
124 }
125 }
126 }
127
128 private static class ServiceEntry {
129 private ServiceURL iSrvURL;
130
131 private List<ServiceLocationAttribute> iAttribs;
132
133 private List<String> iScopes;
134
135
136
137
138
139
140
141
142 public ServiceEntry(ServiceURL pSrvURL, List<ServiceLocationAttribute> pAttribs, List<String> pScopes) {
143 set(pSrvURL, pAttribs, pScopes);
144 }
145
146
147
148
149
150
151
152
153 public void set(ServiceURL pSrvURL, List<ServiceLocationAttribute> pAttribs, List<String> pScopes) {
154 this.iSrvURL = pSrvURL;
155 this.iAttribs = pAttribs;
156 this.iScopes = pScopes;
157 }
158
159
160
161
162
163
164 public ServiceURL getServiceURL() {
165 return this.iSrvURL;
166 }
167
168
169
170
171
172
173 public ServiceType getServiceType() {
174 return this.iSrvURL.getServiceType();
175 }
176
177
178
179
180
181
182 public List<ServiceLocationAttribute> getAttributes() {
183 return this.iAttribs;
184 }
185
186
187
188
189
190
191 public List<String> getScopes() {
192 return this.iScopes;
193 }
194
195
196
197
198
199
200
201 public boolean hasMatchingScope(List<String> pScopes) {
202 if (pScopes == null) return false;
203 Iterator<String> itr = pScopes.iterator();
204 while (itr.hasNext()) if (hasScope(itr.next())) return true;
205 return false;
206 }
207
208 @Override
209 public String toString() {
210 return "url:" + this.iSrvURL + ", attribs:" + dumpList(this.iAttribs) + ", scopes:" + dumpList(this.iScopes);
211 }
212
213 private boolean hasScope(String pScope) {
214 return this.iScopes == null ? false : this.iScopes.contains(pScope);
215 }
216 }
217
218 static class ServiceEntryList extends ArrayList<Object> {
219 private static final long serialVersionUID = 1L;
220
221
222
223
224
225
226
227 public ServiceEntry get(ServiceURL pSrvURL) {
228 for (int i = 0; i < size(); i++) {
229 ServiceEntry entry = (ServiceEntry) get(i);
230 if (pSrvURL.equals(entry.getServiceURL())) return entry;
231 }
232 return null;
233 }
234
235
236
237
238
239
240 public void remove(ServiceURL pSrvURL) {
241 for (int i = 0; i < size(); i++) {
242 ServiceEntry entry = (ServiceEntry) get(i);
243 if (pSrvURL.equals(entry.getServiceURL())) {
244 remove(i);
245 break;
246 }
247 }
248 }
249
250
251
252
253
254
255
256
257 public List<ServiceURL> getServiceURLs(ServiceType pSrvType, List<String> pScopes) {
258 if (pSrvType == null) return null;
259 List<ServiceURL> srvURLs = null;
260 for (int i = 0; i < size(); i++) {
261 ServiceEntry entry = (ServiceEntry) get(i);
262 if (!entry.hasMatchingScope(pScopes)) continue;
263 if (pSrvType.getPrincipleTypeName().equals(entry.getServiceType().getPrincipleTypeName())) {
264 if (srvURLs == null) srvURLs = new ArrayList<ServiceURL>();
265 srvURLs.add(entry.getServiceURL());
266 }
267 }
268 return srvURLs;
269 }
270 }
271
272 private ServiceEntryList iSrvEntryTable = new ServiceEntryList();
273
274 private AddressHashTable iAddressHashTable = new AddressHashTable();
275
276
277
278
279
280
281 public ServiceTable(DatagramThread pDgramThread) {
282 this.iDgramThread = pDgramThread;
283 }
284
285
286
287
288
289
290
291
292
293
294 public synchronized void add(ServiceURL pSrvURL, List<ServiceLocationAttribute> pAttrList, List<String> pScopes)
295 throws UnknownHostException, IOException {
296 if (pSrvURL == null) return;
297 TRC.debug("add URL:" + pSrvURL + ", scopes:" + dumpList(pScopes));
298 ServiceEntry srvEntry = this.iSrvEntryTable.get(pSrvURL);
299 if (srvEntry == null) {
300 this.iSrvEntryTable.add(new ServiceEntry(pSrvURL, pAttrList, pScopes));
301 } else {
302 srvEntry.set(pSrvURL, pAttrList, pScopes);
303 }
304
305 if (!this.iUseV6) return;
306 this.iAddressHashTable.register(pSrvURL.getServiceType());
307 }
308
309
310
311
312
313
314
315
316 public synchronized void remove(ServiceURL pSrvURL) throws UnknownHostException, IOException {
317 this.iSrvEntryTable.remove(pSrvURL);
318
319 if (!this.iUseV6) return;
320 this.iAddressHashTable.unregister(pSrvURL.getServiceType());
321 }
322
323
324
325
326
327
328
329
330 public synchronized List<ServiceURL> getServiceURLs(ServiceType pSrvType, List<String> pScopes) {
331 TRC.debug("getServiceURLs srvType:" + pSrvType + ", scopes:" + dumpList(pScopes));
332 List<ServiceURL> list = this.iSrvEntryTable.getServiceURLs(pSrvType, pScopes);
333 return list;
334 }
335
336
337
338
339
340
341
342
343 public synchronized List<ServiceLocationAttribute> getAttributes(ServiceURL pSrvURL, List<String> pScopes) {
344 if (pSrvURL == null) return null;
345 if (pSrvURL.getURLPath() == null) return getAttributes(pSrvURL.getServiceType(), pScopes);
346 ServiceEntry entry = this.iSrvEntryTable.get(pSrvURL);
347 return entry == null ? null : entry.getAttributes();
348 }
349
350
351
352
353
354
355
356
357 public synchronized List<ServiceLocationAttribute> getAttributes(ServiceType pSrvType, List<String> pScopes) {
358 if (pSrvType == null) return null;
359 HashSet<ServiceLocationAttribute> attribs = new HashSet<ServiceLocationAttribute>();
360 for (int i = 0; i < this.iSrvEntryTable.size(); i++) {
361 ServiceEntry entry = (ServiceEntry) this.iSrvEntryTable.get(i);
362 ServiceType srvType = entry.getServiceType();
363 if (pSrvType.equals(srvType)) attribs.addAll(entry.getAttributes());
364 }
365 return new ArrayList<ServiceLocationAttribute>(attribs);
366 }
367
368
369
370
371
372
373
374 public synchronized List<ServiceType> getServiceTypes(List<String> pScopes) {
375 List<ServiceType> srvTypes = null;
376 for (int i = 0; i < this.iSrvEntryTable.size(); i++) {
377 ServiceEntry entry = (ServiceEntry) this.iSrvEntryTable.get(i);
378 if (entry.hasMatchingScope(pScopes)) {
379 ServiceType srvType = entry.getServiceType();
380 if (srvType == null) continue;
381 if (srvTypes == null) srvTypes = new ArrayList<ServiceType>();
382 srvTypes.add(srvType);
383 }
384 }
385 return srvTypes;
386 }
387
388 static String dumpList(List<?> pList) {
389 return dumpList(pList, ",");
390 }
391
392 private static String dumpList(List<?> pList, String pSep) {
393 if (pList == null) return "null";
394 StringBuffer buf = new StringBuffer();
395 Iterator<?> itr = pList.iterator();
396 boolean first = true;
397 while (itr.hasNext()) {
398 if (!first) buf.append(pSep);
399 buf.append(itr.next().toString());
400 first = false;
401 }
402 return buf.toString();
403 }
404 }