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);
+ });
+ }
+
}