Fixed serialization issue in state handling LDM
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/263c4e0f Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/263c4e0f Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/263c4e0f Branch: refs/heads/WICKET-5906-7.x Commit: 263c4e0fb9afae515a907198211a77d04c47ac6b Parents: 2c2eaf5 Author: Martijn Dashorst <martijn.dasho...@gmail.com> Authored: Sat May 30 22:55:33 2015 +0200 Committer: Andrea Del Bene <âadelb...@apache.orgâ> Committed: Wed Jun 3 10:04:20 2015 +0200 ---------------------------------------------------------------------- .../wicket/model/LoadableDetachableModel.java | 2 +- .../model/LoadableDetachableModelTest.java | 71 ++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/263c4e0f/wicket-core/src/main/java/org/apache/wicket/model/LoadableDetachableModel.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/model/LoadableDetachableModel.java b/wicket-core/src/main/java/org/apache/wicket/model/LoadableDetachableModel.java index 16c6271..75e91bd 100644 --- a/wicket-core/src/main/java/org/apache/wicket/model/LoadableDetachableModel.java +++ b/wicket-core/src/main/java/org/apache/wicket/model/LoadableDetachableModel.java @@ -126,7 +126,7 @@ public abstract class LoadableDetachableModel<T> implements IModel<T> @Override public final T getObject() { - if (state == InternalState.DETACHED) + if (state == null || state == InternalState.DETACHED) { // prevent infinite attachment loops state = InternalState.ATTACHING; http://git-wip-us.apache.org/repos/asf/wicket/blob/263c4e0f/wicket-core/src/test/java/org/apache/wicket/model/LoadableDetachableModelTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/model/LoadableDetachableModelTest.java b/wicket-core/src/test/java/org/apache/wicket/model/LoadableDetachableModelTest.java index a087a78..453bd7b 100644 --- a/wicket-core/src/test/java/org/apache/wicket/model/LoadableDetachableModelTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/model/LoadableDetachableModelTest.java @@ -18,6 +18,13 @@ package org.apache.wicket.model; import static org.hamcrest.core.Is.is; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + import org.apache.wicket.WicketTestCase; import org.junit.Test; @@ -84,4 +91,68 @@ public class LoadableDetachableModelTest extends WicketTestCase assertThat(ldm.isAttached(), is(false)); } } + + private static class SerializedLoad extends LoadableDetachableModel<Integer> + { + private static final long serialVersionUID = 1L; + + private int count = 0; + + @Override + protected Integer load() + { + return ++count; + } + } + + /** + * Tests serialization/deserialization of LDM retaining the correct state. + * + * @throws Exception + */ + @Test + public void serializationDeserializationRetainsInternalState() throws Exception + { + SerializedLoad ldm = new SerializedLoad(); + assertThat(ldm.getObject(), is(1)); + ldm.detach(); + + byte[] serialized = serialize(ldm); + + LoadableDetachableModel<Integer> deserialized = deserialize(serialized); + + assertThat(deserialized.isAttached(), is(false)); + assertThat(deserialized.getObject(), is(2)); + assertThat(deserialized.isAttached(), is(true)); + deserialized.detach(); + assertThat(deserialized.isAttached(), is(false)); + } + + /** Serialization helper */ + @SuppressWarnings("unchecked") + private <T> LoadableDetachableModel<T> deserialize(byte[] serialized) throws IOException, + ClassNotFoundException + { + LoadableDetachableModel<T> deserialized = null; + + try (ByteArrayInputStream bais = new ByteArrayInputStream(serialized); + ObjectInputStream ois = new ObjectInputStream(bais);) + { + deserialized = (LoadableDetachableModel<T>)ois.readObject(); + } + return deserialized; + } + + /** Deserialization helper */ + private byte[] serialize(Serializable ldm) throws IOException + { + byte[] stream = { }; + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos);) + { + oos.writeObject(ldm); + stream = baos.toByteArray(); + } + return stream; + } }