Clover Coverage Report - JmDNS 3.4.1
Coverage timestamp: Thu Aug 25 2011 13:06:33 CEST
../../../img/srcFileCovDistChart6.png 31% of files have more coverage
141   543   78   3.81
68   302   0.55   12.33
37     2.11  
3    
 
  DNSCache       Line # 45 103 0% 51 48 72.7% 0.72727275
  DNSCache._EmptyCache       Line # 56 11 0% 11 22 0% 0.0
  DNSCache._CacheEntry       Line # 151 27 0% 16 31 35.4% 0.35416666
 
  (22)
 
1    // Copyright 2003-2005 Arthur van Hoff Rick Blair
2    // Licensed under Apache License version 2.0
3    // Original license LGPL
4   
5    package javax.jmdns.impl;
6   
7    import java.util.AbstractMap;
8    import java.util.ArrayList;
9    import java.util.Collection;
10    import java.util.Collections;
11    import java.util.HashSet;
12    import java.util.Iterator;
13    import java.util.List;
14    import java.util.Map;
15    import java.util.Set;
16   
17    import javax.jmdns.impl.constants.DNSRecordClass;
18    import javax.jmdns.impl.constants.DNSRecordType;
19   
20    /**
21    * A table of DNS entries. This is a map table which can handle multiple entries with the same name.
22    * <p/>
23    * Storing multiple entries with the same name is implemented using a linked list. This is hidden from the user and can change in later implementation.
24    * <p/>
25    * Here's how to iterate over all entries:
26    *
27    * <pre>
28    * for (Iterator i=dnscache.allValues().iterator(); i.hasNext(); ) {
29    * DNSEntry entry = i.next();
30    * ...do something with entry...
31    * }
32    * </pre>
33    * <p/>
34    * And here's how to iterate over all entries having a given name:
35    *
36    * <pre>
37    * for (Iterator i=dnscache.getDNSEntryList(name).iterator(); i.hasNext(); ) {
38    * DNSEntry entry = i.next();
39    * ...do something with entry...
40    * }
41    * </pre>
42    *
43    * @author Arthur van Hoff, Werner Randelshofer, Rick Blair, Pierre Frisch
44    */
 
45    public class DNSCache extends AbstractMap<String, List<? extends DNSEntry>> {
46   
47    // private static Logger logger = Logger.getLogger(DNSCache.class.getName());
48   
49    private transient Set<Map.Entry<String, List<? extends DNSEntry>>> _entrySet = null;
50   
51    /**
52    *
53    */
54    public static final DNSCache EmptyCache = new _EmptyCache();
55   
 
56    static final class _EmptyCache extends DNSCache {
57   
58    /**
59    * {@inheritDoc}
60    */
 
61  0 toggle @Override
62    public int size() {
63  0 return 0;
64    }
65   
66    /**
67    * {@inheritDoc}
68    */
 
69  0 toggle @Override
70    public boolean isEmpty() {
71  0 return true;
72    }
73   
74    /**
75    * {@inheritDoc}
76    */
 
77  0 toggle @Override
78    public boolean containsKey(Object key) {
79  0 return false;
80    }
81   
82    /**
83    * {@inheritDoc}
84    */
 
85  0 toggle @Override
86    public boolean containsValue(Object value) {
87  0 return false;
88    }
89   
90    /**
91    * {@inheritDoc}
92    */
 
93  0 toggle @Override
94    public List<DNSEntry> get(Object key) {
95  0 return null;
96    }
97   
98    /**
99    * {@inheritDoc}
100    */
 
101  0 toggle @Override
102    public Set<String> keySet() {
103  0 return Collections.emptySet();
104    }
105   
106    /**
107    * {@inheritDoc}
108    */
 
109  0 toggle @Override
110    public Collection<List<? extends DNSEntry>> values() {
111  0 return Collections.emptySet();
112    }
113   
114    /**
115    * {@inheritDoc}
116    */
 
117  0 toggle @Override
118    public Set<Map.Entry<String, List<? extends DNSEntry>>> entrySet() {
119  0 return Collections.emptySet();
120    }
121   
122    /**
123    * {@inheritDoc}
124    */
 
125  0 toggle @Override
126    public boolean equals(Object o) {
127  0 return (o instanceof Map) && ((Map<?, ?>) o).size() == 0;
128    }
129   
130    /**
131    * {@inheritDoc}
132    */
 
133  0 toggle @Override
134    public List<? extends DNSEntry> put(String key, List<? extends DNSEntry> value) {
135  0 return null;
136    }
137   
138    /**
139    * {@inheritDoc}
140    */
 
141  0 toggle @Override
142    public int hashCode() {
143  0 return 0;
144    }
145   
146    }
147   
148    /**
149    *
150    */
 
151    protected static class _CacheEntry extends Object implements Map.Entry<String, List<? extends DNSEntry>> {
152   
153    private List<? extends DNSEntry> _value;
154   
155    private String _key;
156   
157    /**
158    * @param key
159    * @param value
160    */
 
161  92 toggle protected _CacheEntry(String key, List<? extends DNSEntry> value) {
162  91 super();
163  93 _key = (key != null ? key.trim().toLowerCase() : null);
164  95 _value = value;
165    }
166   
167    /**
168    * @param entry
169    */
 
170  0 toggle protected _CacheEntry(Map.Entry<String, List<? extends DNSEntry>> entry) {
171  0 super();
172  0 if (entry instanceof _CacheEntry) {
173  0 _key = ((_CacheEntry) entry).getKey();
174  0 _value = ((_CacheEntry) entry).getValue();
175    }
176    }
177   
178    /**
179    * {@inheritDoc}
180    */
 
181  3211 toggle @Override
182    public String getKey() {
183  3215 return (_key != null ? _key : "");
184    }
185   
186    /**
187    * {@inheritDoc}
188    */
 
189  1758 toggle @Override
190    public List<? extends DNSEntry> getValue() {
191  1759 return _value;
192    }
193   
194    /**
195    * {@inheritDoc}
196    */
 
197  66 toggle @Override
198    public List<? extends DNSEntry> setValue(List<? extends DNSEntry> value) {
199  66 List<? extends DNSEntry> oldValue = _value;
200  66 _value = value;
201  66 return oldValue;
202    }
203   
204    /**
205    * Returns <tt>true</tt> if this list contains no elements.
206    *
207    * @return <tt>true</tt> if this list contains no elements
208    */
 
209  0 toggle public boolean isEmpty() {
210  0 return this.getValue().isEmpty();
211    }
212   
213    /**
214    * {@inheritDoc}
215    */
 
216  0 toggle @Override
217    public boolean equals(Object entry) {
218  0 if (!(entry instanceof Map.Entry)) {
219  0 return false;
220    }
221  0 return this.getKey().equals(((Map.Entry<?, ?>) entry).getKey()) && this.getValue().equals(((Map.Entry<?, ?>) entry).getValue());
222    }
223   
224    /**
225    * {@inheritDoc}
226    */
 
227  101 toggle @Override
228    public int hashCode() {
229  102 return (_key == null ? 0 : _key.hashCode());
230    }
231   
232    /**
233    * {@inheritDoc}
234    */
 
235  0 toggle @Override
236    public synchronized String toString() {
237  0 StringBuffer aLog = new StringBuffer(200);
238  0 aLog.append("\n\t\tname '");
239  0 aLog.append(_key);
240  0 aLog.append("' ");
241  0 if ((_value != null) && (!_value.isEmpty())) {
242  0 for (DNSEntry entry : _value) {
243  0 aLog.append("\n\t\t\t");
244  0 aLog.append(entry.toString());
245    }
246    } else {
247  0 aLog.append(" no entries");
248    }
249  0 return aLog.toString();
250    }
251    }
252   
253    /**
254    *
255    */
 
256  2 toggle public DNSCache() {
257  2 this(1024);
258    }
259   
260    /**
261    * @param map
262    */
 
263  0 toggle public DNSCache(DNSCache map) {
264  0 this(map != null ? map.size() : 1024);
265  0 if (map != null) {
266  0 this.putAll(map);
267    }
268    }
269   
270    /**
271    * Create a table with a given initial size.
272    *
273    * @param initialCapacity
274    */
 
275  31 toggle public DNSCache(int initialCapacity) {
276  31 super();
277  31 _entrySet = new HashSet<Map.Entry<String, List<? extends DNSEntry>>>(initialCapacity);
278    }
279   
280    // ====================================================================
281    // Map
282   
283    /*
284    * (non-Javadoc)
285    * @see java.util.AbstractMap#entrySet()
286    */
 
287  2067 toggle @Override
288    public Set<Map.Entry<String, List<? extends DNSEntry>>> entrySet() {
289  2064 if (_entrySet == null) {
290  0 _entrySet = new HashSet<Map.Entry<String, List<? extends DNSEntry>>>();
291    }
292  2066 return _entrySet;
293    }
294   
295    /**
296    * @param key
297    * @return map entry for the key
298    */
 
299  174 toggle protected Map.Entry<String, List<? extends DNSEntry>> getEntry(String key) {
300  176 String stringKey = (key != null ? key.trim().toLowerCase() : null);
301  178 for (Map.Entry<String, List<? extends DNSEntry>> entry : this.entrySet()) {
302  273 if (stringKey != null) {
303  277 if (stringKey.equals(entry.getKey())) {
304  83 return entry;
305    }
306    } else {
307  0 if (entry.getKey() == null) {
308  0 return entry;
309    }
310    }
311    }
312  95 return null;
313    }
314   
315    /**
316    * {@inheritDoc}
317    */
 
318  0 toggle @Override
319    public List<? extends DNSEntry> put(String key, List<? extends DNSEntry> value) {
320  0 synchronized (this) {
321  0 List<? extends DNSEntry> oldValue = null;
322  0 Map.Entry<String, List<? extends DNSEntry>> oldEntry = this.getEntry(key);
323  0 if (oldEntry != null) {
324  0 oldValue = oldEntry.setValue(value);
325    } else {
326  0 this.entrySet().add(new _CacheEntry(key, value));
327    }
328  0 return oldValue;
329    }
330    }
331   
332    /**
333    * {@inheritDoc}
334    */
 
335  0 toggle @Override
336    protected Object clone() throws CloneNotSupportedException {
337  0 return new DNSCache(this);
338    }
339   
340    // ====================================================================
341   
342    /**
343    * Returns all entries in the cache
344    *
345    * @return all entries in the cache
346    */
 
347  115 toggle public synchronized Collection<DNSEntry> allValues() {
348  115 List<DNSEntry> allValues = new ArrayList<DNSEntry>();
349  114 for (List<? extends DNSEntry> entry : this.values()) {
350  345 if (entry != null) {
351  344 allValues.addAll(entry);
352    }
353    }
354  115 return allValues;
355    }
356   
357    /**
358    * Iterate only over items with matching name. Returns an list of DNSEntry or null. To retrieve all entries, one must iterate over this linked list.
359    *
360    * @param name
361    * @return list of DNSEntries
362    */
 
363  631 toggle public synchronized Collection<? extends DNSEntry> getDNSEntryList(String name) {
364  633 Collection<? extends DNSEntry> entryList = this._getDNSEntryList(name);
365  635 if (entryList != null) {
366  539 entryList = new ArrayList<DNSEntry>(entryList);
367    } else {
368  96 entryList = Collections.emptyList();
369    }
370  626 return entryList;
371    }
372   
 
373  1663 toggle private Collection<? extends DNSEntry> _getDNSEntryList(String name) {
374  1665 return this.get(name != null ? name.toLowerCase() : null);
375    }
376   
377    /**
378    * Get a matching DNS entry from the table (using isSameEntry). Returns the entry that was found.
379    *
380    * @param dnsEntry
381    * @return DNSEntry
382    */
 
383  780 toggle public synchronized DNSEntry getDNSEntry(DNSEntry dnsEntry) {
384  787 DNSEntry result = null;
385  766 if (dnsEntry != null) {
386  778 Collection<? extends DNSEntry> entryList = this._getDNSEntryList(dnsEntry.getKey());
387  783 if (entryList != null) {
388  684 for (DNSEntry testDNSEntry : entryList) {
389  965 if (testDNSEntry.isSameEntry(dnsEntry)) {
390  623 result = testDNSEntry;
391  624 break;
392    }
393    }
394    }
395    }
396  780 return result;
397    }
398   
399    /**
400    * Get a matching DNS entry from the table.
401    *
402    * @param name
403    * @param type
404    * @param recordClass
405    * @return DNSEntry
406    */
 
407  213 toggle public synchronized DNSEntry getDNSEntry(String name, DNSRecordType type, DNSRecordClass recordClass) {
408  214 DNSEntry result = null;
409  215 Collection<? extends DNSEntry> entryList = this._getDNSEntryList(name);
410  213 if (entryList != null) {
411  52 for (DNSEntry testDNSEntry : entryList) {
412  77 if (testDNSEntry.getRecordType().equals(type) && ((DNSRecordClass.CLASS_ANY == recordClass) || testDNSEntry.getRecordClass().equals(recordClass))) {
413  51 result = testDNSEntry;
414  51 break;
415    }
416    }
417    }
418  212 return result;
419    }
420   
421    /**
422    * Get all matching DNS entries from the table.
423    *
424    * @param name
425    * @param type
426    * @param recordClass
427    * @return list of entries
428    */
 
429  42 toggle public synchronized Collection<? extends DNSEntry> getDNSEntryList(String name, DNSRecordType type, DNSRecordClass recordClass) {
430  42 Collection<? extends DNSEntry> entryList = this._getDNSEntryList(name);
431  42 if (entryList != null) {
432  42 entryList = new ArrayList<DNSEntry>(entryList);
433  124 for (Iterator<? extends DNSEntry> i = entryList.iterator(); i.hasNext();) {
434  82 DNSEntry testDNSEntry = i.next();
435  82 if (!testDNSEntry.getRecordType().equals(type) || ((DNSRecordClass.CLASS_ANY != recordClass) && !testDNSEntry.getRecordClass().equals(recordClass))) {
436  41 i.remove();
437    }
438    }
439    } else {
440  0 entryList = Collections.emptyList();
441    }
442  42 return entryList;
443    }
444   
445    /**
446    * Adds an entry to the table.
447    *
448    * @param dnsEntry
449    * @return true if the entry was added
450    */
 
451  148 toggle public synchronized boolean addDNSEntry(final DNSEntry dnsEntry) {
452  153 boolean result = false;
453  153 if (dnsEntry != null) {
454  151 Map.Entry<String, List<? extends DNSEntry>> oldEntry = this.getEntry(dnsEntry.getKey());
455   
456  152 List<DNSEntry> aNewValue = null;
457  152 if (oldEntry != null) {
458  58 aNewValue = new ArrayList<DNSEntry>(oldEntry.getValue());
459    } else {
460  95 aNewValue = new ArrayList<DNSEntry>();
461    }
462  152 aNewValue.add(dnsEntry);
463   
464  151 if (oldEntry != null) {
465  58 oldEntry.setValue(aNewValue);
466    } else {
467  93 this.entrySet().add(new _CacheEntry(dnsEntry.getKey(), aNewValue));
468    }
469    // This is probably not very informative
470  152 result = true;
471    }
472  151 return result;
473    }
474   
475    /**
476    * Removes a specific entry from the table. Returns true if the entry was found.
477    *
478    * @param dnsEntry
479    * @return true if the entry was removed
480    */
 
481  17 toggle public synchronized boolean removeDNSEntry(DNSEntry dnsEntry) {
482  17 boolean result = false;
483  17 if (dnsEntry != null) {
484  17 Map.Entry<String, List<? extends DNSEntry>> existingEntry = this.getEntry(dnsEntry.getKey());
485  17 if (existingEntry != null) {
486  17 result = existingEntry.getValue().remove(dnsEntry);
487    // If we just removed the last one we need to get rid of the entry
488  17 if (existingEntry.getValue().isEmpty()) {
489  10 this.entrySet().remove(existingEntry);
490    }
491    }
492    }
493  17 return result;
494    }
495   
496    /**
497    * Replace an existing entry by a new one.<br/>
498    * <b>Note:</b> the 2 entries must have the same key.
499    *
500    * @param newDNSEntry
501    * @param existingDNSEntry
502    * @return <code>true</code> if the entry has been replace, <code>false</code> otherwise.
503    */
 
504  7 toggle public synchronized boolean replaceDNSEntry(DNSEntry newDNSEntry, DNSEntry existingDNSEntry) {
505  8 boolean result = false;
506  8 if ((newDNSEntry != null) && (existingDNSEntry != null) && (newDNSEntry.getKey().equals(existingDNSEntry.getKey()))) {
507  7 Map.Entry<String, List<? extends DNSEntry>> oldEntry = this.getEntry(newDNSEntry.getKey());
508   
509  7 List<DNSEntry> aNewValue = null;
510  8 if (oldEntry != null) {
511  8 aNewValue = new ArrayList<DNSEntry>(oldEntry.getValue());
512    } else {
513  0 aNewValue = new ArrayList<DNSEntry>();
514    }
515  8 aNewValue.remove(existingDNSEntry);
516  7 aNewValue.add(newDNSEntry);
517   
518  8 if (oldEntry != null) {
519  6 oldEntry.setValue(aNewValue);
520    } else {
521  0 this.entrySet().add(new _CacheEntry(newDNSEntry.getKey(), aNewValue));
522    }
523    // This is probably not very informative
524  7 result = true;
525    }
526  7 return result;
527    }
528   
529    /**
530    * {@inheritDoc}
531    */
 
532  0 toggle @Override
533    public synchronized String toString() {
534  0 StringBuffer aLog = new StringBuffer(2000);
535  0 aLog.append("\t---- cache ----");
536  0 for (Map.Entry<String, List<? extends DNSEntry>> entry : this.entrySet()) {
537  0 aLog.append("\n\t\t");
538  0 aLog.append(entry.toString());
539    }
540  0 return aLog.toString();
541    }
542   
543    }