304 lines
7.0 KiB
Java
304 lines
7.0 KiB
Java
//
|
|
// Source code recreated from a .class file by IntelliJ IDEA
|
|
// (powered by Fernflower decompiler)
|
|
//
|
|
|
|
package dblog;
|
|
|
|
import java.util.AbstractCollection;
|
|
import java.util.AbstractSet;
|
|
import java.util.Collection;
|
|
import java.util.Iterator;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
public class LogMap<K, V, W extends Map<K, V>> implements Map<K, V> {
|
|
final LogMap<K, V, W>.MyLog<K,V> log;
|
|
final W wrapped;
|
|
private Runnable verify;
|
|
private LogMap<K, V, W>.EntrySet esview;
|
|
private LogMap<K, V, W>.KeySet ksview;
|
|
private LogMap<K, V, W>.Values vsview;
|
|
|
|
public LogMap(W wrapped) {
|
|
this.wrapped = wrapped;
|
|
this.log = new LogMap.MyLog();
|
|
}
|
|
|
|
LogMap<K, V, W> setVerify(Runnable verify) {
|
|
this.verify = verify;
|
|
return this;
|
|
}
|
|
|
|
|
|
final LogMap<K, V, W>.MyLog<K,V> myLog() {
|
|
return this.log;
|
|
}
|
|
|
|
public void clear() {
|
|
if (this.verify != null) {
|
|
this.verify.run();
|
|
}
|
|
|
|
this.wrapped.forEach((key, value) -> {
|
|
LogMap.this.myLog().afterRemove(key);
|
|
});
|
|
this.wrapped.clear();
|
|
}
|
|
|
|
public boolean containsKey(Object key) {
|
|
return this.wrapped.containsKey(key);
|
|
}
|
|
|
|
public boolean containsValue(Object value) {
|
|
return this.wrapped.containsValue(value);
|
|
}
|
|
|
|
private Iterator<Entry<K, V>> newEntryIterator() {
|
|
return new LogMap<K, V, W>.WrapEntryIt<Entry<K, V>>() {
|
|
public Entry<K, V> next() {
|
|
return this.nextEntry();
|
|
}
|
|
};
|
|
}
|
|
|
|
public Set<Entry<K, V>> entrySet() {
|
|
return this.esview != null ? this.esview : (this.esview = new LogMap.EntrySet());
|
|
}
|
|
|
|
public V get(Object key) {
|
|
V v = this.wrapped.get(key);
|
|
return v;
|
|
}
|
|
|
|
public int hashCode() {
|
|
return this.wrapped.hashCode();
|
|
}
|
|
|
|
public boolean equals(Object obj) {
|
|
return this.wrapped.equals(obj);
|
|
}
|
|
|
|
public boolean isEmpty() {
|
|
return this.wrapped.isEmpty();
|
|
}
|
|
|
|
private Iterator<K> newKeyIterator() {
|
|
return new LogMap<K, V, W>.WrapEntryIt<K>() {
|
|
public K next() {
|
|
return this.nextEntry().getKey();
|
|
}
|
|
};
|
|
}
|
|
|
|
public Set<K> keySet() {
|
|
return this.ksview != null ? this.ksview : (this.ksview = new LogMap.KeySet());
|
|
}
|
|
|
|
public V put(K key, V value) {
|
|
if (this.verify != null) {
|
|
this.verify.run();
|
|
}
|
|
|
|
if (null != value && null != key) {
|
|
V origin = this.wrapped.put(key, value);
|
|
this.myLog().afterPut(key);
|
|
return origin;
|
|
} else {
|
|
throw new NullPointerException();
|
|
}
|
|
}
|
|
|
|
public void putAll(Map<? extends K, ? extends V> m) {
|
|
if (this.verify != null) {
|
|
this.verify.run();
|
|
}
|
|
|
|
m.forEach((key, value) -> {
|
|
this.put(key, value);
|
|
});
|
|
}
|
|
|
|
public V remove(Object arg0) {
|
|
if (this.verify != null) {
|
|
this.verify.run();
|
|
}
|
|
|
|
V v = this.wrapped.remove(arg0);
|
|
if (null != v) {
|
|
this.myLog().afterRemove(arg0);
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
public int size() {
|
|
return this.wrapped.size();
|
|
}
|
|
|
|
private Iterator<V> newValueIterator() {
|
|
return new LogMap<K, V, W>.WrapEntryIt<V>() {
|
|
public V next() {
|
|
return this.nextEntry().getValue();
|
|
}
|
|
};
|
|
}
|
|
|
|
public Collection<V> values() {
|
|
return this.vsview != null ? this.vsview : (this.vsview = new LogMap.Values());
|
|
}
|
|
|
|
public String toString() {
|
|
return this.wrapped.toString();
|
|
}
|
|
|
|
private final class Values extends AbstractCollection<V> {
|
|
private Values() {
|
|
}
|
|
|
|
public Iterator<V> iterator() {
|
|
return LogMap.this.newValueIterator();
|
|
}
|
|
|
|
public int size() {
|
|
return LogMap.this.size();
|
|
}
|
|
|
|
public boolean contains(Object o) {
|
|
return LogMap.this.containsValue(o);
|
|
}
|
|
|
|
public void clear() {
|
|
LogMap.this.clear();
|
|
}
|
|
}
|
|
|
|
private final class KeySet extends AbstractSet<K> {
|
|
private KeySet() {
|
|
}
|
|
|
|
public Iterator<K> iterator() {
|
|
return LogMap.this.newKeyIterator();
|
|
}
|
|
|
|
public int size() {
|
|
return LogMap.this.size();
|
|
}
|
|
|
|
public boolean contains(Object o) {
|
|
return LogMap.this.containsKey(o);
|
|
}
|
|
|
|
public boolean remove(Object o) {
|
|
return LogMap.this.remove(o) != null;
|
|
}
|
|
|
|
public void clear() {
|
|
LogMap.this.clear();
|
|
}
|
|
}
|
|
|
|
private final class EntrySet extends AbstractSet<Entry<K, V>> {
|
|
private EntrySet() {
|
|
}
|
|
|
|
public Iterator<Entry<K, V>> iterator() {
|
|
return LogMap.this.newEntryIterator();
|
|
}
|
|
|
|
public boolean contains(Object o) {
|
|
return LogMap.this.wrapped.entrySet().contains(o);
|
|
}
|
|
|
|
public int size() {
|
|
return LogMap.this.wrapped.entrySet().size();
|
|
}
|
|
|
|
public boolean remove(Object o) {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
|
|
public void clear() {
|
|
LogMap.this.clear();
|
|
}
|
|
}
|
|
|
|
final class WrapEntry implements Entry<K, V> {
|
|
private Entry<K, V> e;
|
|
|
|
WrapEntry(Entry<K, V> e) {
|
|
this.e = e;
|
|
}
|
|
|
|
public boolean equals(Object obj) {
|
|
return this.e.equals(obj);
|
|
}
|
|
|
|
public K getKey() {
|
|
return this.e.getKey();
|
|
}
|
|
|
|
public V getValue() {
|
|
return this.e.getValue();
|
|
}
|
|
|
|
public int hashCode() {
|
|
return this.e.hashCode();
|
|
}
|
|
|
|
public V setValue(V value) {
|
|
if (LogMap.this.verify != null) {
|
|
LogMap.this.verify.run();
|
|
}
|
|
|
|
if (null == value) {
|
|
throw new NullPointerException();
|
|
} else {
|
|
V origin = this.e.setValue(value);
|
|
LogMap.this.myLog().afterPut(this.e.getKey());
|
|
return origin;
|
|
}
|
|
}
|
|
}
|
|
|
|
abstract class WrapEntryIt<E> implements Iterator<E> {
|
|
private final Iterator<Entry<K, V>> it;
|
|
private LogMap<K, V, W>.WrapEntry current;
|
|
|
|
WrapEntryIt() {
|
|
this.it = LogMap.this.wrapped.entrySet().iterator();
|
|
}
|
|
|
|
WrapEntryIt(Iterator<Entry<K, V>> it) {
|
|
this.it = it;
|
|
}
|
|
|
|
public void remove() {
|
|
if (LogMap.this.verify != null) {
|
|
LogMap.this.verify.run();
|
|
}
|
|
LogMap.this.myLog().afterRemove(this.current.getKey());
|
|
this.it.remove();
|
|
}
|
|
|
|
public boolean hasNext() {
|
|
return this.it.hasNext();
|
|
}
|
|
|
|
Entry<K, V> nextEntry() {
|
|
return this.current = LogMap.this.new WrapEntry((Entry)this.it.next());
|
|
}
|
|
}
|
|
|
|
final class MyLog<K,V> {
|
|
MyLog() {
|
|
}
|
|
|
|
void afterRemove(Object key) {
|
|
}
|
|
|
|
private void afterPut(K key) {
|
|
}
|
|
}
|
|
}
|