diff options
author | Mike Lockwood <lockwood@google.com> | 2012-03-21 12:26:23 -0700 |
---|---|---|
committer | Mike Lockwood <lockwood@google.com> | 2012-03-21 12:26:23 -0700 |
commit | f4eb7466d5c09098f9dc54137ed3235e3c43fc9f (patch) | |
tree | 56e1bf5e433e60e3a18d5a9d08b7d55a64d8ae1d /src/javax/jmdns/impl/DNSCache.java | |
parent | 19376825c9e562c188aef9ccd09a7220bd3c0a20 (diff) | |
parent | 76f0067cea0428b683cba2f187d81e723658f964 (diff) | |
download | jmdns-android-5.1.1_r4.tar.gz |
Merge remote-tracking branch 'goog/ics-aah-exp'android-wear-n-preview-3android-wear-n-preview-2android-wear-n-preview-1android-wear-7.1.1_r1android-wear-5.1.1_r1android-wear-5.1.0_r1android-wear-5.0.0_r1android-sdk-support_r11android-sdk-4.4.2_r1.0.1android-sdk-4.4.2_r1android-n-preview-5android-n-preview-4android-n-preview-3android-n-preview-2android-n-preview-1android-n-iot-preview-2android-m-preview-2android-m-preview-1android-m-previewandroid-l-preview_r2android-cts-6.0_r9android-cts-6.0_r8android-cts-6.0_r7android-cts-6.0_r6android-cts-6.0_r5android-cts-6.0_r4android-cts-6.0_r32android-cts-6.0_r31android-cts-6.0_r30android-cts-6.0_r3android-cts-6.0_r29android-cts-6.0_r28android-cts-6.0_r27android-cts-6.0_r26android-cts-6.0_r25android-cts-6.0_r24android-cts-6.0_r23android-cts-6.0_r22android-cts-6.0_r21android-cts-6.0_r20android-cts-6.0_r2android-cts-6.0_r19android-cts-6.0_r18android-cts-6.0_r17android-cts-6.0_r16android-cts-6.0_r15android-cts-6.0_r14android-cts-6.0_r13android-cts-6.0_r12android-cts-6.0_r1android-cts-5.1_r9android-cts-5.1_r8android-cts-5.1_r7android-cts-5.1_r6android-cts-5.1_r5android-cts-5.1_r4android-cts-5.1_r3android-cts-5.1_r28android-cts-5.1_r27android-cts-5.1_r26android-cts-5.1_r25android-cts-5.1_r24android-cts-5.1_r23android-cts-5.1_r22android-cts-5.1_r21android-cts-5.1_r20android-cts-5.1_r2android-cts-5.1_r19android-cts-5.1_r18android-cts-5.1_r17android-cts-5.1_r16android-cts-5.1_r15android-cts-5.1_r14android-cts-5.1_r13android-cts-5.1_r10android-cts-5.1_r1android-cts-5.0_r9android-cts-5.0_r8android-cts-5.0_r7android-cts-5.0_r6android-cts-5.0_r5android-cts-5.0_r4android-cts-5.0_r3android-cts-4.4_r4android-cts-4.4_r1android-cts-4.2_r2android-cts-4.2_r1android-cts-4.1_r4android-cts-4.1_r2android-cts-4.1_r1android-6.0.1_r9android-6.0.1_r81android-6.0.1_r80android-6.0.1_r8android-6.0.1_r79android-6.0.1_r78android-6.0.1_r77android-6.0.1_r74android-6.0.1_r73android-6.0.1_r72android-6.0.1_r70android-6.0.1_r7android-6.0.1_r69android-6.0.1_r68android-6.0.1_r67android-6.0.1_r66android-6.0.1_r65android-6.0.1_r63android-6.0.1_r62android-6.0.1_r61android-6.0.1_r60android-6.0.1_r59android-6.0.1_r58android-6.0.1_r57android-6.0.1_r56android-6.0.1_r55android-6.0.1_r54android-6.0.1_r53android-6.0.1_r52android-6.0.1_r51android-6.0.1_r50android-6.0.1_r5android-6.0.1_r49android-6.0.1_r48android-6.0.1_r47android-6.0.1_r46android-6.0.1_r45android-6.0.1_r43android-6.0.1_r42android-6.0.1_r41android-6.0.1_r40android-6.0.1_r4android-6.0.1_r33android-6.0.1_r32android-6.0.1_r31android-6.0.1_r30android-6.0.1_r3android-6.0.1_r28android-6.0.1_r27android-6.0.1_r26android-6.0.1_r25android-6.0.1_r24android-6.0.1_r22android-6.0.1_r21android-6.0.1_r20android-6.0.1_r18android-6.0.1_r17android-6.0.1_r16android-6.0.1_r13android-6.0.1_r12android-6.0.1_r11android-6.0.1_r10android-6.0.1_r1android-6.0.0_r7android-6.0.0_r6android-6.0.0_r5android-6.0.0_r41android-6.0.0_r4android-6.0.0_r3android-6.0.0_r26android-6.0.0_r25android-6.0.0_r24android-6.0.0_r23android-6.0.0_r2android-6.0.0_r13android-6.0.0_r12android-6.0.0_r11android-6.0.0_r1android-5.1.1_r9android-5.1.1_r8android-5.1.1_r7android-5.1.1_r6android-5.1.1_r5android-5.1.1_r4android-5.1.1_r38android-5.1.1_r37android-5.1.1_r36android-5.1.1_r35android-5.1.1_r34android-5.1.1_r33android-5.1.1_r30android-5.1.1_r3android-5.1.1_r29android-5.1.1_r28android-5.1.1_r26android-5.1.1_r25android-5.1.1_r24android-5.1.1_r23android-5.1.1_r22android-5.1.1_r20android-5.1.1_r2android-5.1.1_r19android-5.1.1_r18android-5.1.1_r17android-5.1.1_r16android-5.1.1_r15android-5.1.1_r14android-5.1.1_r13android-5.1.1_r12android-5.1.1_r10android-5.1.1_r1android-5.1.0_r5android-5.1.0_r4android-5.1.0_r3android-5.1.0_r1android-5.0.2_r3android-5.0.2_r1android-5.0.1_r1android-5.0.0_r7android-5.0.0_r6android-5.0.0_r5.1android-5.0.0_r5android-5.0.0_r4android-5.0.0_r3android-5.0.0_r2android-5.0.0_r1android-4.4w_r1android-4.4_r1.2.0.1android-4.4_r1.2android-4.4_r1.1.0.1android-4.4_r1.1android-4.4_r1.0.1android-4.4_r1android-4.4_r0.9android-4.4_r0.8android-4.4_r0.7android-4.4.4_r2.0.1android-4.4.4_r2android-4.4.4_r1.0.1android-4.4.4_r1android-4.4.3_r1.1.0.1android-4.4.3_r1.1android-4.4.3_r1.0.1android-4.4.3_r1android-4.4.2_r2.0.1android-4.4.2_r2android-4.4.2_r1.0.1android-4.4.2_r1android-4.4.1_r1.0.1android-4.4.1_r1android-4.3_r3.1android-4.3_r3android-4.3_r2.3android-4.3_r2.2android-4.3_r2.1android-4.3_r2android-4.3_r1.1android-4.3_r1android-4.3_r0.9.1android-4.3_r0.9android-4.3.1_r1android-4.2_r1android-4.2.2_r1.2android-4.2.2_r1.1android-4.2.2_r1android-4.2.1_r1.2android-4.2.1_r1.1android-4.2.1_r1android-4.1.2_r2.1android-4.1.2_r2android-4.1.2_r1android-4.1.1_r6.1android-4.1.1_r6android-4.1.1_r5android-4.1.1_r4android-4.1.1_r3android-4.1.1_r2android-4.1.1_r1.1android-4.1.1_r1tools_r22.2tools_r22tools_r21nougat-mr1-wear-releasen-iot-preview-2master-soongmarshmallow-releasemarshmallow-mr3-releasemarshmallow-mr2-releasemarshmallow-mr1-releasemarshmallow-mr1-devmarshmallow-dr1.6-releasemarshmallow-dr1.5-releasemarshmallow-dr1.5-devmarshmallow-dr-releasemarshmallow-dr-dragon-releasemarshmallow-dr-devmarshmallow-devmarshmallow-cts-releaselollipop-wear-releaselollipop-releaselollipop-mr1-wfc-releaselollipop-mr1-releaselollipop-mr1-fi-releaselollipop-mr1-devlollipop-mr1-cts-releaselollipop-devlollipop-cts-releasel-previewkitkat-wearkitkat-releasekitkat-mr2.2-releasekitkat-mr2.1-releasekitkat-mr2-releasekitkat-mr1.1-releasekitkat-mr1-releasekitkat-devkitkat-cts-releasekitkat-cts-devjb-releasejb-mr2.0.0-releasejb-mr2.0-releasejb-mr2-releasejb-mr2-devjb-mr1.1-releasejb-mr1.1-dev-plus-aospjb-mr1.1-devjb-mr1-releasejb-mr1-dev-plus-aospjb-mr1-devjb-mr0-releasejb-devidea133-weekly-releaseidea133
Diffstat (limited to 'src/javax/jmdns/impl/DNSCache.java')
-rw-r--r-- | src/javax/jmdns/impl/DNSCache.java | 543 |
1 files changed, 543 insertions, 0 deletions
diff --git a/src/javax/jmdns/impl/DNSCache.java b/src/javax/jmdns/impl/DNSCache.java new file mode 100644 index 0000000..ed26f0d --- /dev/null +++ b/src/javax/jmdns/impl/DNSCache.java @@ -0,0 +1,543 @@ +// Copyright 2003-2005 Arthur van Hoff Rick Blair +// Licensed under Apache License version 2.0 +// Original license LGPL + +package javax.jmdns.impl; + +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.jmdns.impl.constants.DNSRecordClass; +import javax.jmdns.impl.constants.DNSRecordType; + +/** + * A table of DNS entries. This is a map table which can handle multiple entries with the same name. + * <p/> + * 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. + * <p/> + * Here's how to iterate over all entries: + * + * <pre> + * for (Iterator i=dnscache.allValues().iterator(); i.hasNext(); ) { + * DNSEntry entry = i.next(); + * ...do something with entry... + * } + * </pre> + * <p/> + * And here's how to iterate over all entries having a given name: + * + * <pre> + * for (Iterator i=dnscache.getDNSEntryList(name).iterator(); i.hasNext(); ) { + * DNSEntry entry = i.next(); + * ...do something with entry... + * } + * </pre> + * + * @author Arthur van Hoff, Werner Randelshofer, Rick Blair, Pierre Frisch + */ +public class DNSCache extends AbstractMap<String, List<? extends DNSEntry>> { + + // private static Logger logger = Logger.getLogger(DNSCache.class.getName()); + + private transient Set<Map.Entry<String, List<? extends DNSEntry>>> _entrySet = null; + + /** + * + */ + public static final DNSCache EmptyCache = new _EmptyCache(); + + static final class _EmptyCache extends DNSCache { + + /** + * {@inheritDoc} + */ + @Override + public int size() { + return 0; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isEmpty() { + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean containsKey(Object key) { + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean containsValue(Object value) { + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public List<DNSEntry> get(Object key) { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public Set<String> keySet() { + return Collections.emptySet(); + } + + /** + * {@inheritDoc} + */ + @Override + public Collection<List<? extends DNSEntry>> values() { + return Collections.emptySet(); + } + + /** + * {@inheritDoc} + */ + @Override + public Set<Map.Entry<String, List<? extends DNSEntry>>> entrySet() { + return Collections.emptySet(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object o) { + return (o instanceof Map) && ((Map<?, ?>) o).size() == 0; + } + + /** + * {@inheritDoc} + */ + @Override + public List<? extends DNSEntry> put(String key, List<? extends DNSEntry> value) { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return 0; + } + + } + + /** + * + */ + protected static class _CacheEntry extends Object implements Map.Entry<String, List<? extends DNSEntry>> { + + private List<? extends DNSEntry> _value; + + private String _key; + + /** + * @param key + * @param value + */ + protected _CacheEntry(String key, List<? extends DNSEntry> value) { + super(); + _key = (key != null ? key.trim().toLowerCase() : null); + _value = value; + } + + /** + * @param entry + */ + protected _CacheEntry(Map.Entry<String, List<? extends DNSEntry>> entry) { + super(); + if (entry instanceof _CacheEntry) { + _key = ((_CacheEntry) entry).getKey(); + _value = ((_CacheEntry) entry).getValue(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public String getKey() { + return (_key != null ? _key : ""); + } + + /** + * {@inheritDoc} + */ + @Override + public List<? extends DNSEntry> getValue() { + return _value; + } + + /** + * {@inheritDoc} + */ + @Override + public List<? extends DNSEntry> setValue(List<? extends DNSEntry> value) { + List<? extends DNSEntry> oldValue = _value; + _value = value; + return oldValue; + } + + /** + * Returns <tt>true</tt> if this list contains no elements. + * + * @return <tt>true</tt> if this list contains no elements + */ + public boolean isEmpty() { + return this.getValue().isEmpty(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object entry) { + if (!(entry instanceof Map.Entry)) { + return false; + } + return this.getKey().equals(((Map.Entry<?, ?>) entry).getKey()) && this.getValue().equals(((Map.Entry<?, ?>) entry).getValue()); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return (_key == null ? 0 : _key.hashCode()); + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized String toString() { + StringBuffer aLog = new StringBuffer(200); + aLog.append("\n\t\tname '"); + aLog.append(_key); + aLog.append("' "); + if ((_value != null) && (!_value.isEmpty())) { + for (DNSEntry entry : _value) { + aLog.append("\n\t\t\t"); + aLog.append(entry.toString()); + } + } else { + aLog.append(" no entries"); + } + return aLog.toString(); + } + } + + /** + * + */ + public DNSCache() { + this(1024); + } + + /** + * @param map + */ + public DNSCache(DNSCache map) { + this(map != null ? map.size() : 1024); + if (map != null) { + this.putAll(map); + } + } + + /** + * Create a table with a given initial size. + * + * @param initialCapacity + */ + public DNSCache(int initialCapacity) { + super(); + _entrySet = new HashSet<Map.Entry<String, List<? extends DNSEntry>>>(initialCapacity); + } + + // ==================================================================== + // Map + + /* + * (non-Javadoc) + * @see java.util.AbstractMap#entrySet() + */ + @Override + public Set<Map.Entry<String, List<? extends DNSEntry>>> entrySet() { + if (_entrySet == null) { + _entrySet = new HashSet<Map.Entry<String, List<? extends DNSEntry>>>(); + } + return _entrySet; + } + + /** + * @param key + * @return map entry for the key + */ + protected Map.Entry<String, List<? extends DNSEntry>> getEntry(String key) { + String stringKey = (key != null ? key.trim().toLowerCase() : null); + for (Map.Entry<String, List<? extends DNSEntry>> entry : this.entrySet()) { + if (stringKey != null) { + if (stringKey.equals(entry.getKey())) { + return entry; + } + } else { + if (entry.getKey() == null) { + return entry; + } + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public List<? extends DNSEntry> put(String key, List<? extends DNSEntry> value) { + synchronized (this) { + List<? extends DNSEntry> oldValue = null; + Map.Entry<String, List<? extends DNSEntry>> oldEntry = this.getEntry(key); + if (oldEntry != null) { + oldValue = oldEntry.setValue(value); + } else { + this.entrySet().add(new _CacheEntry(key, value)); + } + return oldValue; + } + } + + /** + * {@inheritDoc} + */ + @Override + protected Object clone() throws CloneNotSupportedException { + return new DNSCache(this); + } + + // ==================================================================== + + /** + * Returns all entries in the cache + * + * @return all entries in the cache + */ + public synchronized Collection<DNSEntry> allValues() { + List<DNSEntry> allValues = new ArrayList<DNSEntry>(); + for (List<? extends DNSEntry> entry : this.values()) { + if (entry != null) { + allValues.addAll(entry); + } + } + return allValues; + } + + /** + * 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. + * + * @param name + * @return list of DNSEntries + */ + public synchronized Collection<? extends DNSEntry> getDNSEntryList(String name) { + Collection<? extends DNSEntry> entryList = this._getDNSEntryList(name); + if (entryList != null) { + entryList = new ArrayList<DNSEntry>(entryList); + } else { + entryList = Collections.emptyList(); + } + return entryList; + } + + private Collection<? extends DNSEntry> _getDNSEntryList(String name) { + return this.get(name != null ? name.toLowerCase() : null); + } + + /** + * Get a matching DNS entry from the table (using isSameEntry). Returns the entry that was found. + * + * @param dnsEntry + * @return DNSEntry + */ + public synchronized DNSEntry getDNSEntry(DNSEntry dnsEntry) { + DNSEntry result = null; + if (dnsEntry != null) { + Collection<? extends DNSEntry> entryList = this._getDNSEntryList(dnsEntry.getKey()); + if (entryList != null) { + for (DNSEntry testDNSEntry : entryList) { + if (testDNSEntry.isSameEntry(dnsEntry)) { + result = testDNSEntry; + break; + } + } + } + } + return result; + } + + /** + * Get a matching DNS entry from the table. + * + * @param name + * @param type + * @param recordClass + * @return DNSEntry + */ + public synchronized DNSEntry getDNSEntry(String name, DNSRecordType type, DNSRecordClass recordClass) { + DNSEntry result = null; + Collection<? extends DNSEntry> entryList = this._getDNSEntryList(name); + if (entryList != null) { + for (DNSEntry testDNSEntry : entryList) { + if (testDNSEntry.getRecordType().equals(type) && ((DNSRecordClass.CLASS_ANY == recordClass) || testDNSEntry.getRecordClass().equals(recordClass))) { + result = testDNSEntry; + break; + } + } + } + return result; + } + + /** + * Get all matching DNS entries from the table. + * + * @param name + * @param type + * @param recordClass + * @return list of entries + */ + public synchronized Collection<? extends DNSEntry> getDNSEntryList(String name, DNSRecordType type, DNSRecordClass recordClass) { + Collection<? extends DNSEntry> entryList = this._getDNSEntryList(name); + if (entryList != null) { + entryList = new ArrayList<DNSEntry>(entryList); + for (Iterator<? extends DNSEntry> i = entryList.iterator(); i.hasNext();) { + DNSEntry testDNSEntry = i.next(); + if (!testDNSEntry.getRecordType().equals(type) || ((DNSRecordClass.CLASS_ANY != recordClass) && !testDNSEntry.getRecordClass().equals(recordClass))) { + i.remove(); + } + } + } else { + entryList = Collections.emptyList(); + } + return entryList; + } + + /** + * Adds an entry to the table. + * + * @param dnsEntry + * @return true if the entry was added + */ + public synchronized boolean addDNSEntry(final DNSEntry dnsEntry) { + boolean result = false; + if (dnsEntry != null) { + Map.Entry<String, List<? extends DNSEntry>> oldEntry = this.getEntry(dnsEntry.getKey()); + + List<DNSEntry> aNewValue = null; + if (oldEntry != null) { + aNewValue = new ArrayList<DNSEntry>(oldEntry.getValue()); + } else { + aNewValue = new ArrayList<DNSEntry>(); + } + aNewValue.add(dnsEntry); + + if (oldEntry != null) { + oldEntry.setValue(aNewValue); + } else { + this.entrySet().add(new _CacheEntry(dnsEntry.getKey(), aNewValue)); + } + // This is probably not very informative + result = true; + } + return result; + } + + /** + * Removes a specific entry from the table. Returns true if the entry was found. + * + * @param dnsEntry + * @return true if the entry was removed + */ + public synchronized boolean removeDNSEntry(DNSEntry dnsEntry) { + boolean result = false; + if (dnsEntry != null) { + Map.Entry<String, List<? extends DNSEntry>> existingEntry = this.getEntry(dnsEntry.getKey()); + if (existingEntry != null) { + result = existingEntry.getValue().remove(dnsEntry); + // If we just removed the last one we need to get rid of the entry + if (existingEntry.getValue().isEmpty()) { + this.entrySet().remove(existingEntry); + } + } + } + return result; + } + + /** + * Replace an existing entry by a new one.<br/> + * <b>Note:</b> the 2 entries must have the same key. + * + * @param newDNSEntry + * @param existingDNSEntry + * @return <code>true</code> if the entry has been replace, <code>false</code> otherwise. + */ + public synchronized boolean replaceDNSEntry(DNSEntry newDNSEntry, DNSEntry existingDNSEntry) { + boolean result = false; + if ((newDNSEntry != null) && (existingDNSEntry != null) && (newDNSEntry.getKey().equals(existingDNSEntry.getKey()))) { + Map.Entry<String, List<? extends DNSEntry>> oldEntry = this.getEntry(newDNSEntry.getKey()); + + List<DNSEntry> aNewValue = null; + if (oldEntry != null) { + aNewValue = new ArrayList<DNSEntry>(oldEntry.getValue()); + } else { + aNewValue = new ArrayList<DNSEntry>(); + } + aNewValue.remove(existingDNSEntry); + aNewValue.add(newDNSEntry); + + if (oldEntry != null) { + oldEntry.setValue(aNewValue); + } else { + this.entrySet().add(new _CacheEntry(newDNSEntry.getKey(), aNewValue)); + } + // This is probably not very informative + result = true; + } + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized String toString() { + StringBuffer aLog = new StringBuffer(2000); + aLog.append("\t---- cache ----"); + for (Map.Entry<String, List<? extends DNSEntry>> entry : this.entrySet()) { + aLog.append("\n\t\t"); + aLog.append(entry.toString()); + } + return aLog.toString(); + } + +} |