You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/06/28 05:53:52 UTC
[isis] branch master updated: ISIS-3049: early guard against incompatible scalar type for scalar panel with text-field
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 46335e25e8 ISIS-3049: early guard against incompatible scalar type for scalar panel with text-field
46335e25e8 is described below
commit 46335e25e80d0896b09f9094ce9182f782d4aef5
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Jun 28 07:53:46 2022 +0200
ISIS-3049: early guard against incompatible scalar type for scalar panel
with text-field
- also convert anonymous component factories to static ones
---
.../scalars/ScalarPanelTextFieldAbstract.java | 17 ++-
.../ComponentFactoryRegistrarDefault.java | 144 +++++++++++----------
2 files changed, 86 insertions(+), 75 deletions(-)
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
index 1a0c46d559..34338eca28 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
@@ -59,6 +59,7 @@ extends ScalarPanelFormFieldAbstract<T> {
final ScalarModel scalarModel,
final Class<T> type) {
super(id, scalarModel, type);
+ guardAgainstIncompatibleScalarType();
}
// -- CONVERSION
@@ -92,13 +93,6 @@ extends ScalarPanelFormFieldAbstract<T> {
}
protected final IModel<T> unwrappedModel() {
- _Assert.assertTrue(scalarModel().getScalarTypeSpec().isAssignableFrom(type), ()->
- String.format("[%s:%s] cannot possibly unwrap model of type %s into target type %s",
- this.getClass().getSimpleName(),
- scalarModel().getIdentifier(),
- scalarModel().getScalarTypeSpec().getCorrespondingClass(),
- type));
-
return scalarModel().unwrapped(type);
}
@@ -138,6 +132,15 @@ extends ScalarPanelFormFieldAbstract<T> {
// -- HELPER
+ private void guardAgainstIncompatibleScalarType() {
+ _Assert.assertTrue(scalarModel().getScalarTypeSpec().isAssignableFrom(type), ()->
+ String.format("[%s:%s] cannot possibly unwrap model of type %s into target type %s",
+ this.getClass().getSimpleName(),
+ scalarModel().getIdentifier(),
+ scalarModel().getScalarTypeSpec().getCorrespondingClass(),
+ type));
+ }
+
<F extends FormComponent<?>> F applyFormComponentAttributes(final F formComponent) {
val scalarModel = scalarModel();
Wkt.setFormComponentAttributes(formComponent,
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
index 910d070049..dd63fad31d 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
@@ -225,17 +225,8 @@ public class ComponentFactoryRegistrarDefault implements ComponentFactoryRegistr
componentFactories.add(new IsisBlobPanelFactory());
componentFactories.add(new IsisClobPanelFactory());
- val registeredScalarTypes =
- componentFactories.stream(ComponentFactoryScalarAbstract.class)
- .flatMap(f->f.getScalarTypes().stream())
- .collect(Collectors.toSet());
-
- valueSemanticsResolver.streamClassesWithValueSemantics()
- .filter(_Predicates.not(registeredScalarTypes::contains))
- .flatMap(valueSemanticsResolver::streamValueSemantics)
- //.peek(valueSemantics->System.err.printf("%s -> %s%n", valueSemantics, valueSemantics.getCorrespondingClass().getName()))
- .map(valueSemantics->createForValueSemantics((ValueSemanticsProvider)valueSemantics))
- .forEach(componentFactories::add);
+ // install after explicit values, but before fallbacks
+ addGenericComponentFactoriesForScalar(componentFactories);
componentFactories.add(new ValueFallbackPanelFactory());
@@ -289,100 +280,117 @@ public class ComponentFactoryRegistrarDefault implements ComponentFactoryRegistr
createForValueSemantics(final ValueSemanticsProvider<T> valueSemantics) {
if(valueSemantics.isNumberType()) {
- return createScalarPanelUsingNumberField(valueSemantics.getCorrespondingClass());
+ return new ScalarPanelFactoryForNumberField<T>(valueSemantics.getCorrespondingClass());
}
if(valueSemantics.isTemporalType()) {
- return createScalarPanelUsingTemporalPicker(valueSemantics.getCorrespondingClass());
+ return new ScalarPanelFactoryForTemporalPicker<T>(valueSemantics.getCorrespondingClass());
}
if(valueSemantics.isCompositeType()) {
- return createScalarPanelForComposite(valueSemantics.getCorrespondingClass());
+ return new ScalarPanelFactoryForCompositeValue<T>(valueSemantics.getCorrespondingClass());
}
- return createScalarPanelUsingTextField(valueSemantics.getCorrespondingClass());
+ return new ScalarPanelFactoryForTextField<T>(valueSemantics.getCorrespondingClass());
}
- public static <T extends Serializable> ComponentFactoryScalarAbstract
- createScalarPanelUsingTextField(final Class<T> valueTypeClass) {
+ public static class ScalarPanelFactoryForTextField<T extends Serializable>
+ extends ComponentFactoryScalarAbstract {
- var valueTypeClasses = withPrimitiveVariant(valueTypeClass);
+ private static final long serialVersionUID = 1L;
- return new ComponentFactoryScalarAbstract(
- ScalarPanelTextFieldWithValueSemantics.class,
- valueTypeClasses) {
+ private final Class<T> valueTypeClass;
- private static final long serialVersionUID = 1L;
-
- @Override
- public Component createComponent(final String id, final ScalarModel scalarModel) {
- return new ScalarPanelTextFieldWithValueSemantics<T>(id, scalarModel, valueTypeClass);
- }
+ protected ScalarPanelFactoryForTextField(final Class<T> valueTypeClass) {
+ super(ScalarPanelTextFieldWithValueSemantics.class, withPrimitiveVariant(valueTypeClass));
+ this.valueTypeClass = valueTypeClass;
+ }
- };
+ @Override
+ public Component createComponent(final String id, final ScalarModel scalarModel) {
+ return new ScalarPanelTextFieldWithValueSemantics<T>(id, scalarModel, valueTypeClass);
+ }
}
- public static <T extends Serializable> ComponentFactoryScalarAbstract
- createScalarPanelUsingNumberField(final Class<T> valueTypeClass) {
- var valueTypeClasses = withPrimitiveVariant(valueTypeClass);
+ public static class ScalarPanelFactoryForNumberField<T extends Serializable>
+ extends ComponentFactoryScalarAbstract {
- return new ComponentFactoryScalarAbstract(
- ScalarPanelTextFieldNumeric.class,
- valueTypeClasses) {
+ private static final long serialVersionUID = 1L;
- private static final long serialVersionUID = 1L;
+ private final Class<T> valueTypeClass;
- @Override
- public Component createComponent(final String id, final ScalarModel scalarModel) {
- return new ScalarPanelTextFieldNumeric<T>(id, scalarModel, valueTypeClass);
- }
+ protected ScalarPanelFactoryForNumberField(final Class<T> valueTypeClass) {
+ super(ScalarPanelTextFieldNumeric.class, withPrimitiveVariant(valueTypeClass));
+ this.valueTypeClass = valueTypeClass;
+ }
- };
+ @Override
+ public Component createComponent(final String id, final ScalarModel scalarModel) {
+ return new ScalarPanelTextFieldNumeric<T>(id, scalarModel, valueTypeClass);
+ }
}
- public static <T extends Serializable> ComponentFactoryScalarAbstract
- createScalarPanelUsingTemporalPicker(final Class<T> valueTypeClass) {
-
- // assuming there is no primitive temporal type
- val valueTypeClasses = Can.<Class<?>>ofSingleton(valueTypeClass);
+ public static class ScalarPanelFactoryForTemporalPicker<T extends Serializable>
+ extends ComponentFactoryScalarAbstract {
- return new ComponentFactoryScalarAbstract(
- ScalarPanelTextFieldWithTemporalPicker.class,
- valueTypeClasses) {
+ private static final long serialVersionUID = 1L;
- private static final long serialVersionUID = 1L;
+ private final Class<T> valueTypeClass;
- @Override
- public Component createComponent(final String id, final ScalarModel scalarModel) {
- return new ScalarPanelTextFieldWithTemporalPicker<T>(id, scalarModel, valueTypeClass);
- }
+ protected ScalarPanelFactoryForTemporalPicker(final Class<T> valueTypeClass) {
+ super(ScalarPanelTextFieldWithTemporalPicker.class,
+ // assuming there is no primitive temporal type
+ Can.<Class<?>>ofSingleton(valueTypeClass));
+ this.valueTypeClass = valueTypeClass;
+ }
- };
+ @Override
+ public Component createComponent(final String id, final ScalarModel scalarModel) {
+ return new ScalarPanelTextFieldWithTemporalPicker<T>(id, scalarModel, valueTypeClass);
+ }
}
- public static <T extends Serializable> ComponentFactoryScalarAbstract
- createScalarPanelForComposite(final Class<T> valueTypeClass) {
+ public static class ScalarPanelFactoryForCompositeValue<T extends Serializable>
+ extends ComponentFactoryScalarAbstract {
- // assuming there is no primitive composite type
- val valueTypeClasses = Can.<Class<?>>ofSingleton(valueTypeClass);
+ private static final long serialVersionUID = 1L;
- return new ComponentFactoryScalarAbstract(
- CompositeValuePanel.class,
- valueTypeClasses) {
+ private final Class<T> valueTypeClass;
- private static final long serialVersionUID = 1L;
-
- @Override
- public Component createComponent(final String id, final ScalarModel scalarModel) {
- return new CompositeValuePanel<T>(id, scalarModel, valueTypeClass);
- }
+ protected ScalarPanelFactoryForCompositeValue(final Class<T> valueTypeClass) {
+ super(CompositeValuePanel.class,
+ // assuming there is no primitive composite type
+ Can.<Class<?>>ofSingleton(valueTypeClass));
+ this.valueTypeClass = valueTypeClass;
+ }
- };
+ @Override
+ public Component createComponent(final String id, final ScalarModel scalarModel) {
+ return new CompositeValuePanel<T>(id, scalarModel, valueTypeClass);
+ }
}
// -- HELPER
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private void addGenericComponentFactoriesForScalar(
+ final ComponentFactoryList componentFactories) {
+
+ // collect those registered up to this point, so we don't override with generic ones at steps below
+ val registeredScalarTypes =
+ componentFactories.stream(ComponentFactoryScalarAbstract.class)
+ .flatMap(f->f.getScalarTypes().stream())
+ .collect(Collectors.toSet());
+
+ valueSemanticsResolver.streamClassesWithValueSemantics()
+ .filter(_Predicates.not(registeredScalarTypes::contains))
+ .flatMap(valueSemanticsResolver::streamValueSemantics)
+ //.peek(valueSemantics->System.err.printf("%s -> %s%n", valueSemantics, valueSemantics.getCorrespondingClass().getName()))
+ .map(valueSemantics->createForValueSemantics((ValueSemanticsProvider)valueSemantics))
+ .forEach(componentFactories::add);
+ }
+
private static Can<Class<?>> withPrimitiveVariant(final @NonNull Class<?> valueTypeClass) {
var valueTypeClasses = Can.<Class<?>>ofSingleton(valueTypeClass);