#939 - Make ModifyAwareSet serializable ... (for serializable entity beans with @DbJson etc)

This commit is contained in:
Rob Bygrave
2017-01-09 19:39:54 +13:00
parent 8467934021
commit 335cef870f
10 changed files with 245 additions and 130 deletions
@@ -1,118 +0,0 @@
package io.ebeaninternal.server.type;
import java.util.Collection;
import java.util.Iterator;
/**
* Wraps a collection for the purposes of detecting modifications.
*/
public class ModifyAwareCollection<E> implements Collection<E> {
protected final ModifyAwareOwner owner;
protected final Collection<E> c;
/**
* Create with an Owner and the underlying collection this wraps.
* <p>
* The owner is notified of the additions and removals.
* </p>
*/
public ModifyAwareCollection(ModifyAwareOwner owner, Collection<E> c) {
this.owner = owner;
this.c = c;
}
public String toString() {
return c.toString();
}
public boolean add(E o) {
if (c.add(o)) {
owner.markAsModified();
return true;
}
return false;
}
public boolean addAll(Collection<? extends E> collection) {
boolean changed = false;
for (E o : collection) {
if (c.add(o)) {
owner.markAsModified();
changed = true;
}
}
return changed;
}
public void clear() {
if (!c.isEmpty()) {
owner.markAsModified();
}
c.clear();
}
public boolean contains(Object o) {
return c.contains(o);
}
public boolean containsAll(Collection<?> collection) {
return c.containsAll(collection);
}
public boolean isEmpty() {
return c.isEmpty();
}
public Iterator<E> iterator() {
return new ModifyAwareIterator<>(owner, c.iterator());
}
public boolean remove(Object o) {
if (c.remove(o)) {
owner.markAsModified();
return true;
}
return false;
}
public boolean removeAll(Collection<?> collection) {
boolean changed = false;
for (Object element : collection) {
if (c.remove(element)) {
owner.markAsModified();
changed = true;
}
}
return changed;
}
public boolean retainAll(Collection<?> collection) {
boolean changed = false;
Iterator<?> it = c.iterator();
while (it.hasNext()) {
Object o = it.next();
if (!collection.contains(o)) {
it.remove();
owner.markAsModified();
changed = true;
}
}
return changed;
}
public int size() {
return c.size();
}
public Object[] toArray() {
return c.toArray();
}
public <T> T[] toArray(T[] a) {
//noinspection SuspiciousToArrayCall
return c.toArray(a);
}
}
@@ -5,6 +5,8 @@ package io.ebeaninternal.server.type;
*/
public class ModifyAwareFlag implements ModifyAwareOwner {
private static final long serialVersionUID = 1;
boolean dirty;
@Override
@@ -11,6 +11,8 @@ import java.util.ListIterator;
*/
public class ModifyAwareList<E> implements List<E>, ModifyAwareOwner {
private static final long serialVersionUID = 1;
final List<E> list;
final ModifyAwareOwner owner;
@@ -1,6 +1,7 @@
package io.ebeaninternal.server.type;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@@ -9,6 +10,8 @@ import java.util.Set;
*/
public class ModifyAwareMap<K, V> implements Map<K, V>, ModifyAwareOwner {
private static final long serialVersionUID = 1;
final ModifyAwareOwner owner;
/**
@@ -107,7 +110,7 @@ public class ModifyAwareMap<K, V> implements Map<K, V>, ModifyAwareOwner {
@Override
public Collection<V> values() {
return new ModifyAwareCollection<>(this, map.values());
return new ModifyAwareSet<>(this, new LinkedHashSet<>(map.values()));
}
@Override
@@ -1,9 +1,11 @@
package io.ebeaninternal.server.type;
import java.io.Serializable;
/**
* Owner object notified when a modification is detected.
*/
public interface ModifyAwareOwner {
public interface ModifyAwareOwner extends Serializable {
/**
* Return true if the value is considered dirty.
@@ -1,24 +1,33 @@
package io.ebeaninternal.server.type;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
/**
* Wraps a Set for the purposes of detecting modifications.
*/
public class ModifyAwareSet<E> extends ModifyAwareCollection<E> implements Set<E>, ModifyAwareOwner {
public class ModifyAwareSet<E> implements Set<E>, ModifyAwareOwner {
/**
* Create with an Owner that is notified of modifications.
*/
public ModifyAwareSet(ModifyAwareOwner owner, Set<E> s) {
super(owner, s);
}
private static final long serialVersionUID = 1;
protected final ModifyAwareOwner owner;
protected final Set<E> set;
/**
* Create as top level with it's own ModifyAwareOwner instance wrapping the given Set.
*/
public ModifyAwareSet(Set<E> s) {
super(new ModifyAwareFlag(), s);
public ModifyAwareSet(Set<E> underlying) {
this(new ModifyAwareFlag(), underlying);
}
/**
* Create with an Owner that is notified of modifications.
*/
public ModifyAwareSet(ModifyAwareOwner owner, Set<E> underlying) {
this.owner = owner;
this.set = underlying;
}
@Override
@@ -35,4 +44,96 @@ public class ModifyAwareSet<E> extends ModifyAwareCollection<E> implements Set<E
public void resetMarkedDirty() {
owner.resetMarkedDirty();
}
public String toString() {
return set.toString();
}
public boolean add(E o) {
if (set.add(o)) {
owner.markAsModified();
return true;
}
return false;
}
public boolean addAll(Collection<? extends E> collection) {
boolean changed = false;
for (E o : collection) {
if (set.add(o)) {
owner.markAsModified();
changed = true;
}
}
return changed;
}
public void clear() {
if (!set.isEmpty()) {
owner.markAsModified();
}
set.clear();
}
public boolean contains(Object o) {
return set.contains(o);
}
public boolean containsAll(Collection<?> collection) {
return set.containsAll(collection);
}
public boolean isEmpty() {
return set.isEmpty();
}
public Iterator<E> iterator() {
return new ModifyAwareIterator<>(owner, set.iterator());
}
public boolean remove(Object o) {
if (set.remove(o)) {
owner.markAsModified();
return true;
}
return false;
}
public boolean removeAll(Collection<?> collection) {
boolean changed = false;
for (Object element : collection) {
if (set.remove(element)) {
owner.markAsModified();
changed = true;
}
}
return changed;
}
public boolean retainAll(Collection<?> collection) {
boolean changed = false;
Iterator<?> it = set.iterator();
while (it.hasNext()) {
Object o = it.next();
if (!collection.contains(o)) {
it.remove();
owner.markAsModified();
changed = true;
}
}
return changed;
}
public int size() {
return set.size();
}
public Object[] toArray() {
return set.toArray();
}
public <T> T[] toArray(T[] a) {
return set.toArray(a);
}
}