Go to the documentation of this file.00001
00002
00003
00004
00005 package javax.jmdns.impl;
00006
00007 import java.util.AbstractMap;
00008 import java.util.ArrayList;
00009 import java.util.Collection;
00010 import java.util.Collections;
00011 import java.util.HashSet;
00012 import java.util.Iterator;
00013 import java.util.List;
00014 import java.util.Map;
00015 import java.util.Set;
00016
00017 import javax.jmdns.impl.constants.DNSRecordClass;
00018 import javax.jmdns.impl.constants.DNSRecordType;
00019
00045 public class DNSCache extends AbstractMap<String, List<? extends DNSEntry>> {
00046
00047
00048
00049 private transient Set<Map.Entry<String, List<? extends DNSEntry>>> _entrySet = null;
00050
00054 public static final DNSCache EmptyCache = new _EmptyCache();
00055
00056 static final class _EmptyCache extends DNSCache {
00057
00061 @Override
00062 public int size() {
00063 return 0;
00064 }
00065
00069 @Override
00070 public boolean isEmpty() {
00071 return true;
00072 }
00073
00077 @Override
00078 public boolean containsKey(Object key) {
00079 return false;
00080 }
00081
00085 @Override
00086 public boolean containsValue(Object value) {
00087 return false;
00088 }
00089
00093 @Override
00094 public List<DNSEntry> get(Object key) {
00095 return null;
00096 }
00097
00101 @Override
00102 public Set<String> keySet() {
00103 return Collections.emptySet();
00104 }
00105
00109 @Override
00110 public Collection<List<? extends DNSEntry>> values() {
00111 return Collections.emptySet();
00112 }
00113
00117 @Override
00118 public Set<Map.Entry<String, List<? extends DNSEntry>>> entrySet() {
00119 return Collections.emptySet();
00120 }
00121
00125 @Override
00126 public boolean equals(Object o) {
00127 return (o instanceof Map) && ((Map<?, ?>) o).size() == 0;
00128 }
00129
00133 @Override
00134 public List<? extends DNSEntry> put(String key, List<? extends DNSEntry> value) {
00135 return null;
00136 }
00137
00141 @Override
00142 public int hashCode() {
00143 return 0;
00144 }
00145
00146 }
00147
00151 protected static class _CacheEntry extends Object implements Map.Entry<String, List<? extends DNSEntry>> {
00152
00153 private List<? extends DNSEntry> _value;
00154
00155 private String _key;
00156
00161 protected _CacheEntry(String key, List<? extends DNSEntry> value) {
00162 super();
00163 _key = (key != null ? key.trim().toLowerCase() : null);
00164 _value = value;
00165 }
00166
00170 protected _CacheEntry(Map.Entry<String, List<? extends DNSEntry>> entry) {
00171 super();
00172 if (entry instanceof _CacheEntry) {
00173 _key = ((_CacheEntry) entry).getKey();
00174 _value = ((_CacheEntry) entry).getValue();
00175 }
00176 }
00177
00181 @Override
00182 public String getKey() {
00183 return (_key != null ? _key : "");
00184 }
00185
00189 @Override
00190 public List<? extends DNSEntry> getValue() {
00191 return _value;
00192 }
00193
00197 @Override
00198 public List<? extends DNSEntry> setValue(List<? extends DNSEntry> value) {
00199 List<? extends DNSEntry> oldValue = _value;
00200 _value = value;
00201 return oldValue;
00202 }
00203
00209 public boolean isEmpty() {
00210 return this.getValue().isEmpty();
00211 }
00212
00216 @Override
00217 public boolean equals(Object entry) {
00218 if (!(entry instanceof Map.Entry)) {
00219 return false;
00220 }
00221 return this.getKey().equals(((Map.Entry<?, ?>) entry).getKey()) && this.getValue().equals(((Map.Entry<?, ?>) entry).getValue());
00222 }
00223
00227 @Override
00228 public int hashCode() {
00229 return (_key == null ? 0 : _key.hashCode());
00230 }
00231
00235 @Override
00236 public synchronized String toString() {
00237 StringBuffer aLog = new StringBuffer(200);
00238 aLog.append("\n\t\tname '");
00239 aLog.append(_key);
00240 aLog.append("' ");
00241 if ((_value != null) && (!_value.isEmpty())) {
00242 for (DNSEntry entry : _value) {
00243 aLog.append("\n\t\t\t");
00244 aLog.append(entry.toString());
00245 }
00246 } else {
00247 aLog.append(" no entries");
00248 }
00249 return aLog.toString();
00250 }
00251 }
00252
00256 public DNSCache() {
00257 this(1024);
00258 }
00259
00263 public DNSCache(DNSCache map) {
00264 this(map != null ? map.size() : 1024);
00265 if (map != null) {
00266 this.putAll(map);
00267 }
00268 }
00269
00275 public DNSCache(int initialCapacity) {
00276 super();
00277 _entrySet = new HashSet<Map.Entry<String, List<? extends DNSEntry>>>(initialCapacity);
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287 @Override
00288 public Set<Map.Entry<String, List<? extends DNSEntry>>> entrySet() {
00289 if (_entrySet == null) {
00290 _entrySet = new HashSet<Map.Entry<String, List<? extends DNSEntry>>>();
00291 }
00292 return _entrySet;
00293 }
00294
00299 protected Map.Entry<String, List<? extends DNSEntry>> getEntry(String key) {
00300 String stringKey = (key != null ? key.trim().toLowerCase() : null);
00301 for (Map.Entry<String, List<? extends DNSEntry>> entry : this.entrySet()) {
00302 if (stringKey != null) {
00303 if (stringKey.equals(entry.getKey())) {
00304 return entry;
00305 }
00306 } else {
00307 if (entry.getKey() == null) {
00308 return entry;
00309 }
00310 }
00311 }
00312 return null;
00313 }
00314
00318 @Override
00319 public List<? extends DNSEntry> put(String key, List<? extends DNSEntry> value) {
00320 synchronized (this) {
00321 List<? extends DNSEntry> oldValue = null;
00322 Map.Entry<String, List<? extends DNSEntry>> oldEntry = this.getEntry(key);
00323 if (oldEntry != null) {
00324 oldValue = oldEntry.setValue(value);
00325 } else {
00326 this.entrySet().add(new _CacheEntry(key, value));
00327 }
00328 return oldValue;
00329 }
00330 }
00331
00335 @Override
00336 protected Object clone() throws CloneNotSupportedException {
00337 return new DNSCache(this);
00338 }
00339
00340
00341
00347 public synchronized Collection<DNSEntry> allValues() {
00348 List<DNSEntry> allValues = new ArrayList<DNSEntry>();
00349 for (List<? extends DNSEntry> entry : this.values()) {
00350 if (entry != null) {
00351 allValues.addAll(entry);
00352 }
00353 }
00354 return allValues;
00355 }
00356
00363 public synchronized Collection<? extends DNSEntry> getDNSEntryList(String name) {
00364 Collection<? extends DNSEntry> entryList = this._getDNSEntryList(name);
00365 if (entryList != null) {
00366 entryList = new ArrayList<DNSEntry>(entryList);
00367 } else {
00368 entryList = Collections.emptyList();
00369 }
00370 return entryList;
00371 }
00372
00373 private Collection<? extends DNSEntry> _getDNSEntryList(String name) {
00374 return this.get(name != null ? name.toLowerCase() : null);
00375 }
00376
00383 public synchronized DNSEntry getDNSEntry(DNSEntry dnsEntry) {
00384 DNSEntry result = null;
00385 if (dnsEntry != null) {
00386 Collection<? extends DNSEntry> entryList = this._getDNSEntryList(dnsEntry.getKey());
00387 if (entryList != null) {
00388 for (DNSEntry testDNSEntry : entryList) {
00389 if (testDNSEntry.isSameEntry(dnsEntry)) {
00390 result = testDNSEntry;
00391 break;
00392 }
00393 }
00394 }
00395 }
00396 return result;
00397 }
00398
00407 public synchronized DNSEntry getDNSEntry(String name, DNSRecordType type, DNSRecordClass recordClass) {
00408 DNSEntry result = null;
00409 Collection<? extends DNSEntry> entryList = this._getDNSEntryList(name);
00410 if (entryList != null) {
00411 for (DNSEntry testDNSEntry : entryList) {
00412 if (testDNSEntry.getRecordType().equals(type) && ((DNSRecordClass.CLASS_ANY == recordClass) || testDNSEntry.getRecordClass().equals(recordClass))) {
00413 result = testDNSEntry;
00414 break;
00415 }
00416 }
00417 }
00418 return result;
00419 }
00420
00429 public synchronized Collection<? extends DNSEntry> getDNSEntryList(String name, DNSRecordType type, DNSRecordClass recordClass) {
00430 Collection<? extends DNSEntry> entryList = this._getDNSEntryList(name);
00431 if (entryList != null) {
00432 entryList = new ArrayList<DNSEntry>(entryList);
00433 for (Iterator<? extends DNSEntry> i = entryList.iterator(); i.hasNext();) {
00434 DNSEntry testDNSEntry = i.next();
00435 if (!testDNSEntry.getRecordType().equals(type) || ((DNSRecordClass.CLASS_ANY != recordClass) && !testDNSEntry.getRecordClass().equals(recordClass))) {
00436 i.remove();
00437 }
00438 }
00439 } else {
00440 entryList = Collections.emptyList();
00441 }
00442 return entryList;
00443 }
00444
00451 public synchronized boolean addDNSEntry(final DNSEntry dnsEntry) {
00452 boolean result = false;
00453 if (dnsEntry != null) {
00454 Map.Entry<String, List<? extends DNSEntry>> oldEntry = this.getEntry(dnsEntry.getKey());
00455
00456 List<DNSEntry> aNewValue = null;
00457 if (oldEntry != null) {
00458 aNewValue = new ArrayList<DNSEntry>(oldEntry.getValue());
00459 } else {
00460 aNewValue = new ArrayList<DNSEntry>();
00461 }
00462 aNewValue.add(dnsEntry);
00463
00464 if (oldEntry != null) {
00465 oldEntry.setValue(aNewValue);
00466 } else {
00467 this.entrySet().add(new _CacheEntry(dnsEntry.getKey(), aNewValue));
00468 }
00469
00470 result = true;
00471 }
00472 return result;
00473 }
00474
00481 public synchronized boolean removeDNSEntry(DNSEntry dnsEntry) {
00482 boolean result = false;
00483 if (dnsEntry != null) {
00484 Map.Entry<String, List<? extends DNSEntry>> existingEntry = this.getEntry(dnsEntry.getKey());
00485 if (existingEntry != null) {
00486 result = existingEntry.getValue().remove(dnsEntry);
00487
00488 if (existingEntry.getValue().isEmpty()) {
00489 this.entrySet().remove(existingEntry);
00490 }
00491 }
00492 }
00493 return result;
00494 }
00495
00504 public synchronized boolean replaceDNSEntry(DNSEntry newDNSEntry, DNSEntry existingDNSEntry) {
00505 boolean result = false;
00506 if ((newDNSEntry != null) && (existingDNSEntry != null) && (newDNSEntry.getKey().equals(existingDNSEntry.getKey()))) {
00507 Map.Entry<String, List<? extends DNSEntry>> oldEntry = this.getEntry(newDNSEntry.getKey());
00508
00509 List<DNSEntry> aNewValue = null;
00510 if (oldEntry != null) {
00511 aNewValue = new ArrayList<DNSEntry>(oldEntry.getValue());
00512 } else {
00513 aNewValue = new ArrayList<DNSEntry>();
00514 }
00515 aNewValue.remove(existingDNSEntry);
00516 aNewValue.add(newDNSEntry);
00517
00518 if (oldEntry != null) {
00519 oldEntry.setValue(aNewValue);
00520 } else {
00521 this.entrySet().add(new _CacheEntry(newDNSEntry.getKey(), aNewValue));
00522 }
00523
00524 result = true;
00525 }
00526 return result;
00527 }
00528
00532 @Override
00533 public synchronized String toString() {
00534 StringBuffer aLog = new StringBuffer(2000);
00535 aLog.append("\t---- cache ----");
00536 for (Map.Entry<String, List<? extends DNSEntry>> entry : this.entrySet()) {
00537 aLog.append("\n\t\t");
00538 aLog.append(entry.toString());
00539 }
00540 return aLog.toString();
00541 }
00542
00543 }