diff --git a/src/main/java/io/ebeaninternal/server/type/ModifyAwareCollection.java b/src/main/java/io/ebeaninternal/server/type/ModifyAwareCollection.java deleted file mode 100644 index 710cab5df..000000000 --- a/src/main/java/io/ebeaninternal/server/type/ModifyAwareCollection.java +++ /dev/null @@ -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 implements Collection { - - protected final ModifyAwareOwner owner; - - protected final Collection c; - - /** - * Create with an Owner and the underlying collection this wraps. - *

- * The owner is notified of the additions and removals. - *

- */ - public ModifyAwareCollection(ModifyAwareOwner owner, Collection 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 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 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[] toArray(T[] a) { - //noinspection SuspiciousToArrayCall - return c.toArray(a); - } - -} diff --git a/src/main/java/io/ebeaninternal/server/type/ModifyAwareFlag.java b/src/main/java/io/ebeaninternal/server/type/ModifyAwareFlag.java index 066652fd8..d7e827f39 100644 --- a/src/main/java/io/ebeaninternal/server/type/ModifyAwareFlag.java +++ b/src/main/java/io/ebeaninternal/server/type/ModifyAwareFlag.java @@ -5,6 +5,8 @@ package io.ebeaninternal.server.type; */ public class ModifyAwareFlag implements ModifyAwareOwner { + private static final long serialVersionUID = 1; + boolean dirty; @Override diff --git a/src/main/java/io/ebeaninternal/server/type/ModifyAwareList.java b/src/main/java/io/ebeaninternal/server/type/ModifyAwareList.java index 7bd8b88d2..11becd35d 100644 --- a/src/main/java/io/ebeaninternal/server/type/ModifyAwareList.java +++ b/src/main/java/io/ebeaninternal/server/type/ModifyAwareList.java @@ -11,6 +11,8 @@ import java.util.ListIterator; */ public class ModifyAwareList implements List, ModifyAwareOwner { + private static final long serialVersionUID = 1; + final List list; final ModifyAwareOwner owner; diff --git a/src/main/java/io/ebeaninternal/server/type/ModifyAwareMap.java b/src/main/java/io/ebeaninternal/server/type/ModifyAwareMap.java index f0bc0a1f1..8e2b76318 100644 --- a/src/main/java/io/ebeaninternal/server/type/ModifyAwareMap.java +++ b/src/main/java/io/ebeaninternal/server/type/ModifyAwareMap.java @@ -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 implements Map, ModifyAwareOwner { + private static final long serialVersionUID = 1; + final ModifyAwareOwner owner; /** @@ -107,7 +110,7 @@ public class ModifyAwareMap implements Map, ModifyAwareOwner { @Override public Collection values() { - return new ModifyAwareCollection<>(this, map.values()); + return new ModifyAwareSet<>(this, new LinkedHashSet<>(map.values())); } @Override diff --git a/src/main/java/io/ebeaninternal/server/type/ModifyAwareOwner.java b/src/main/java/io/ebeaninternal/server/type/ModifyAwareOwner.java index 2333bbd79..47976986e 100644 --- a/src/main/java/io/ebeaninternal/server/type/ModifyAwareOwner.java +++ b/src/main/java/io/ebeaninternal/server/type/ModifyAwareOwner.java @@ -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. diff --git a/src/main/java/io/ebeaninternal/server/type/ModifyAwareSet.java b/src/main/java/io/ebeaninternal/server/type/ModifyAwareSet.java index 4affcbc41..365eff2b4 100644 --- a/src/main/java/io/ebeaninternal/server/type/ModifyAwareSet.java +++ b/src/main/java/io/ebeaninternal/server/type/ModifyAwareSet.java @@ -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 extends ModifyAwareCollection implements Set, ModifyAwareOwner { +public class ModifyAwareSet implements Set, ModifyAwareOwner { - /** - * Create with an Owner that is notified of modifications. - */ - public ModifyAwareSet(ModifyAwareOwner owner, Set s) { - super(owner, s); - } + private static final long serialVersionUID = 1; + + protected final ModifyAwareOwner owner; + + protected final Set set; /** * Create as top level with it's own ModifyAwareOwner instance wrapping the given Set. */ - public ModifyAwareSet(Set s) { - super(new ModifyAwareFlag(), s); + public ModifyAwareSet(Set underlying) { + this(new ModifyAwareFlag(), underlying); + } + + /** + * Create with an Owner that is notified of modifications. + */ + public ModifyAwareSet(ModifyAwareOwner owner, Set underlying) { + this.owner = owner; + this.set = underlying; } @Override @@ -35,4 +44,96 @@ public class ModifyAwareSet extends ModifyAwareCollection implements Set 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 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[] toArray(T[] a) { + return set.toArray(a); + } } diff --git a/src/test/java/io/ebeaninternal/server/type/ModifyAwareFlagTest.java b/src/test/java/io/ebeaninternal/server/type/ModifyAwareFlagTest.java new file mode 100644 index 000000000..84312de65 --- /dev/null +++ b/src/test/java/io/ebeaninternal/server/type/ModifyAwareFlagTest.java @@ -0,0 +1,33 @@ +package io.ebeaninternal.server.type; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ModifyAwareFlagTest { + + @Test + public void serialise() throws IOException, ClassNotFoundException { + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(os); + + ModifyAwareFlag flag = new ModifyAwareFlag(); + flag.markAsModified(); + oos.writeObject(flag); + oos.flush(); + oos.close(); + + ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(is); + + ModifyAwareFlag read = (ModifyAwareFlag)ois.readObject(); + assertThat(read.isMarkedDirty()).isTrue(); + } +} diff --git a/src/test/java/io/ebeaninternal/server/type/ModifyAwareListTest.java b/src/test/java/io/ebeaninternal/server/type/ModifyAwareListTest.java index 76aa28b69..98fbd8d2d 100644 --- a/src/test/java/io/ebeaninternal/server/type/ModifyAwareListTest.java +++ b/src/test/java/io/ebeaninternal/server/type/ModifyAwareListTest.java @@ -2,13 +2,21 @@ package io.ebeaninternal.server.type; import org.junit.Test; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.ListIterator; -import static org.junit.Assert.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; public class ModifyAwareListTest { @@ -242,4 +250,22 @@ public class ModifyAwareListTest { assertTrue(set.isMarkedDirty()); } + + @Test + public void serialise() throws IOException, ClassNotFoundException { + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(os); + + ModifyAwareList orig = createList(); + oos.writeObject(orig); + oos.flush(); + oos.close(); + + ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(is); + + ModifyAwareList read = (ModifyAwareList)ois.readObject(); + assertThat(read).contains("A", "B", "C", "D", "E"); + } } diff --git a/src/test/java/io/ebeaninternal/server/type/ModifyAwareMapTest.java b/src/test/java/io/ebeaninternal/server/type/ModifyAwareMapTest.java index 622a2eca1..e8fca2ed4 100644 --- a/src/test/java/io/ebeaninternal/server/type/ModifyAwareMapTest.java +++ b/src/test/java/io/ebeaninternal/server/type/ModifyAwareMapTest.java @@ -2,12 +2,19 @@ package io.ebeaninternal.server.type; import org.junit.Test; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.*; public class ModifyAwareMapTest { @@ -181,4 +188,22 @@ public class ModifyAwareMapTest { assertEquals(map.size(), entries.size()); assertFalse(map.isMarkedDirty()); } + + @Test + public void serialise() throws IOException, ClassNotFoundException { + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(os); + + ModifyAwareMap orig = createMap(); + oos.writeObject(orig); + oos.flush(); + oos.close(); + + ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(is); + + ModifyAwareMap read = (ModifyAwareMap)ois.readObject(); + assertThat(read).hasSize(orig.size()); + } } diff --git a/src/test/java/io/ebeaninternal/server/type/ModifyAwareSetTest.java b/src/test/java/io/ebeaninternal/server/type/ModifyAwareSetTest.java new file mode 100644 index 000000000..dbe0b3226 --- /dev/null +++ b/src/test/java/io/ebeaninternal/server/type/ModifyAwareSetTest.java @@ -0,0 +1,39 @@ +package io.ebeaninternal.server.type; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Arrays; +import java.util.HashSet; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ModifyAwareSetTest { + + private ModifyAwareSet createSet() { + HashSet set = new HashSet<>(); + set.addAll(Arrays.asList("A", "B", "C", "D", "E")); + return new ModifyAwareSet<>(set); + } + + @Test + public void serialise() throws IOException, ClassNotFoundException { + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(os); + + oos.writeObject(createSet()); + oos.flush(); + oos.close(); + + ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(is); + + ModifyAwareSet read = (ModifyAwareSet)ois.readObject(); + assertThat(read).contains("A", "B", "C", "D", "E"); + } +}