You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by ad...@apache.org on 2023/10/23 08:26:12 UTC

[wicket] 03/04: Easier to work with polymorphic values inside IModel

This is an automated email from the ASF dual-hosted git repository.

adelbene pushed a commit to branch wicket-9.x
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit 74bea4555695d3f64e30abba077149c451ea0749
Author: Andreas Svanberg <an...@mensa.se>
AuthorDate: Thu Oct 19 19:00:32 2023 +0200

    Easier to work with polymorphic values inside IModel
---
 .../main/java/org/apache/wicket/model/IModel.java  | 13 ++++++++
 .../java/org/apache/wicket/model/IModelTest.java   | 38 ++++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/wicket-core/src/main/java/org/apache/wicket/model/IModel.java b/wicket-core/src/main/java/org/apache/wicket/model/IModel.java
index c9db790548..e9799682ea 100644
--- a/wicket-core/src/main/java/org/apache/wicket/model/IModel.java
+++ b/wicket-core/src/main/java/org/apache/wicket/model/IModel.java
@@ -370,6 +370,19 @@ public interface IModel<T> extends IDetachable
 		};
 	}
 
+	/**
+	 * Returns an IModel, returning the object typed as {@code R} if it is an instance of that type,
+	 * otherwise {@code null}.
+	 *
+	 * @param <R> the type the object should be an instance of
+	 * @param clazz the {@code Class} the current model object should be an instance of
+	 * @return a new IModel
+	 */
+	default <R extends T> IModel<R> poly(Class<R> clazz) {
+		Args.notNull(clazz, "clazz");
+		return filter(clazz::isInstance).map(clazz::cast);
+	}
+
 	/**
 	 * Suppresses generics warning when casting model types.
 	 *
diff --git a/wicket-core/src/test/java/org/apache/wicket/model/IModelTest.java b/wicket-core/src/test/java/org/apache/wicket/model/IModelTest.java
index e0cf82dcc6..09d1a1dc40 100644
--- a/wicket-core/src/test/java/org/apache/wicket/model/IModelTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/model/IModelTest.java
@@ -234,4 +234,42 @@ class IModelTest
 		assertNotNull(clone);
 		assertEquals("Some Name", clone.getObject());
 	}
+
+	sealed interface TextMatchingStatus
+	{
+		record NotSubmitted() implements TextMatchingStatus {}
+		record Queued() implements TextMatchingStatus {}
+		record Analysed(int matchingInPercent) implements TextMatchingStatus {}
+		record Error(int errorCode, String humanReadableMessage) implements TextMatchingStatus {}
+	}
+
+	@Test
+	void polymorphicModelWrongClass()
+	{
+		IModel<TextMatchingStatus> statusModel = LoadableDetachableModel.of(() ->
+				new TextMatchingStatus.Error(3, "File too big"));
+		IModel<TextMatchingStatus.Queued> poly = statusModel.poly(TextMatchingStatus.Queued.class);
+
+		assertNull(poly.getObject());
+	}
+
+	@Test
+	void polymorphicModelCorrectClass()
+	{
+		IModel<TextMatchingStatus> statusModel = LoadableDetachableModel.of(() ->
+				new TextMatchingStatus.Analysed(14));
+		IModel<TextMatchingStatus.Analysed> poly = statusModel.poly(TextMatchingStatus.Analysed.class);
+
+		assertNotNull(poly.getObject());
+		assertEquals(new TextMatchingStatus.Analysed(14), poly.getObject());
+	}
+
+	@Test
+	void nullPoly()
+	{
+		assertThrows(IllegalArgumentException.class, () -> {
+			LoadableDetachableModel.of(TextMatchingStatus.NotSubmitted::new).poly(null);
+		});
+	}
+
 }