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/causeway.git


The following commit(s) were added to refs/heads/master by this push:
     new 999b2dedfb CAUSEWAY-3489: temporal decomposition support for non 
java.time temporal types
999b2dedfb is described below

commit 999b2dedfb90dc645e8c2514aeea0cdccf4612c8
Author: Andi Huber <[email protected]>
AuthorDate: Thu Mar 14 20:26:36 2024 +0100

    CAUSEWAY-3489: temporal decomposition support for non java.time temporal
    types
    
    - e.g. Joda
---
 .../semantics/TemporalCharacteristicsProvider.java | 96 ++++++++++++++++++++++
 .../value/semantics/TemporalValueSemantics.java    | 75 +----------------
 .../causeway/core/metamodel/util/Facets.java       | 14 +++-
 .../valuetypes/TemporalSemanticsAdapter.java       | 15 +++-
 .../TemporalValueSemanticsProviderTest.java        |  4 +-
 .../viewer/wicket/model/models/ScalarModel.java    | 12 +--
 .../value/ConverterBasedOnValueSemantics.java      | 16 ++++
 .../test/components/scalars/ConverterTester.java   |  3 +-
 .../ScalarPanelTextFieldWithTemporalPicker.java    | 20 ++---
 .../scalars/datepicker/TemporalDecomposition.java  | 25 +++---
 10 files changed, 167 insertions(+), 113 deletions(-)

diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/value/semantics/TemporalCharacteristicsProvider.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/value/semantics/TemporalCharacteristicsProvider.java
new file mode 100644
index 0000000000..88d5805fec
--- /dev/null
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/value/semantics/TemporalCharacteristicsProvider.java
@@ -0,0 +1,96 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.causeway.applib.value.semantics;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import lombok.val;
+
+public interface TemporalCharacteristicsProvider {
+
+    static enum TemporalCharacteristic {
+
+        /**
+         * Temporal value type has no date information, just time.
+         */
+        TIME_ONLY,
+
+        /**
+         * Temporal value type has no time information, just date.
+         */
+        DATE_ONLY,
+
+        /**
+         * Temporal value type has both date and time information.
+         */
+        DATE_TIME
+    }
+
+    static enum OffsetCharacteristic {
+
+        /**
+         * Temporal value type has no time-zone data.
+         */
+        LOCAL,
+
+        /**
+         * Temporal value type has time-zone offset data.
+         */
+        OFFSET,
+
+        /**
+         * Temporal value type has time-zone id data.
+         */
+        ZONED;
+
+        public boolean isLocal() {return this == LOCAL;}
+        public boolean isOffset() {return this == OFFSET;}
+        public boolean isZoned() {return this == ZONED;}
+    }
+
+    TemporalCharacteristic getTemporalCharacteristic();
+    OffsetCharacteristic getOffsetCharacteristic();
+
+    /**
+     * For temporal value editing, provides the list of available time zones 
to choose from.
+     */
+    default List<ZoneId> getAvailableZoneIds() {
+        return ZoneId.getAvailableZoneIds().stream()
+            .sorted()
+            .map(ZoneId::of)
+            .collect(Collectors.toList());
+    }
+
+    /**
+     * For temporal value editing, provides the list of available offsets to 
choose from.
+     */
+    default List<ZoneOffset> getAvailableOffsets() {
+        val now = LocalDateTime.now();
+        return getAvailableZoneIds().stream()
+            .map(ZoneId::getRules)
+            .flatMap(zoneIdRules->zoneIdRules.getValidOffsets(now).stream())
+            .sorted()
+            .distinct()
+            .collect(Collectors.toList());
+    }
+}
diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/value/semantics/TemporalValueSemantics.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/value/semantics/TemporalValueSemantics.java
index 7709ad1883..b715413488 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/value/semantics/TemporalValueSemantics.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/value/semantics/TemporalValueSemantics.java
@@ -19,19 +19,13 @@
 package org.apache.causeway.applib.value.semantics;
 
 import java.time.Duration;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
 import java.time.temporal.Temporal;
-import java.util.List;
-import java.util.stream.Collectors;
 
 import org.apache.causeway.applib.annotation.TimePrecision;
 import org.apache.causeway.commons.internal.exceptions._Exceptions;
 
 import lombok.Data;
 import lombok.NonNull;
-import lombok.val;
 
 /**
  * Common base for {@link java.time.temporal.Temporal} value types.
@@ -44,50 +38,8 @@ public interface TemporalValueSemantics<T extends Temporal>
 extends
     OrderRelation<T, Duration>,
     Parser<T>,
-    Renderer<T> {
-
-    static enum TemporalCharacteristic {
-
-        /**
-         * Temporal value type has no date information, just time.
-         */
-        TIME_ONLY,
-
-        /**
-         * Temporal value type has no time information, just date.
-         */
-        DATE_ONLY,
-
-        /**
-         * Temporal value type has both date and time information.
-         */
-        DATE_TIME
-    }
-
-    static enum OffsetCharacteristic {
-
-        /**
-         * Temporal value type has no time-zone data.
-         */
-        LOCAL,
-
-        /**
-         * Temporal value type has time-zone offset data.
-         */
-        OFFSET,
-
-        /**
-         * Temporal value type has time-zone id data.
-         */
-        ZONED;
-
-        public boolean isLocal() {return this == LOCAL;}
-        public boolean isOffset() {return this == OFFSET;}
-        public boolean isZoned() {return this == ZONED;}
-    }
-
-    TemporalCharacteristic getTemporalCharacteristic();
-    OffsetCharacteristic getOffsetCharacteristic();
+    Renderer<T>,
+    TemporalCharacteristicsProvider {
 
     static enum EditingFormatDirection {
 
@@ -355,27 +307,4 @@ extends
 
     }
 
-    /**
-     * For temporal value editing, provides the list of available time zones 
to choose from.
-     */
-    default List<ZoneId> getAvailableZoneIds() {
-        return ZoneId.getAvailableZoneIds().stream()
-            .sorted()
-            .map(ZoneId::of)
-            .collect(Collectors.toList());
-    }
-
-    /**
-     * For temporal value editing, provides the list of available offsets to 
choose from.
-     */
-    default List<ZoneOffset> getAvailableOffsets() {
-        val now = LocalDateTime.now();
-        return getAvailableZoneIds().stream()
-            .map(ZoneId::getRules)
-            .flatMap(zoneIdRules->zoneIdRules.getValidOffsets(now).stream())
-            .sorted()
-            .distinct()
-            .collect(Collectors.toList());
-    }
-
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/util/Facets.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/util/Facets.java
index 1bc3fd0149..9d0b026768 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/util/Facets.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/util/Facets.java
@@ -34,7 +34,7 @@ import org.apache.causeway.applib.annotation.TableDecorator;
 import org.apache.causeway.applib.annotation.Where;
 import org.apache.causeway.applib.id.LogicalType;
 import org.apache.causeway.applib.layout.grid.bootstrap.BSGrid;
-import org.apache.causeway.applib.value.semantics.TemporalValueSemantics;
+import 
org.apache.causeway.applib.value.semantics.TemporalCharacteristicsProvider;
 import org.apache.causeway.applib.value.semantics.ValueSemanticsProvider;
 import org.apache.causeway.commons.collections.Can;
 import org.apache.causeway.commons.internal.base._Casts;
@@ -446,11 +446,19 @@ public final class Facets {
     }
 
     @SuppressWarnings("unchecked")
-    public Optional<TemporalValueSemantics<?>> valueTemporalSemantics(final 
ObjectSpecification objectSpec) {
+    public Optional<TemporalCharacteristicsProvider> 
valueTemporalAndOffsetCharacteristics(
+            final ObjectSpecification objectSpec) {
         return objectSpec.valueFacet()
             .flatMap(valueFacet->valueFacet.getAllValueSemantics().stream()
                     .findFirst())
-            
.flatMap(valueSemantics->_Casts.castTo(TemporalValueSemantics.class, 
valueSemantics));
+            
.flatMap(valueSemantics->_Casts.castTo(TemporalCharacteristicsProvider.class, 
valueSemantics));
+    }
+
+    public TemporalCharacteristicsProvider 
valueTemporalAndOffsetCharacteristicsElseFail(
+            final ObjectSpecification objectSpec) {
+        return valueTemporalAndOffsetCharacteristics(objectSpec)
+                .orElseThrow(()->_Exceptions.illegalState("no temporal 
characteristics found for %s",
+                        objectSpec));
     }
 
     // -- HELPER
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/valuetypes/TemporalSemanticsAdapter.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/valuetypes/TemporalSemanticsAdapter.java
index 7bee824756..a6e265fd73 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/valuetypes/TemporalSemanticsAdapter.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/valuetypes/TemporalSemanticsAdapter.java
@@ -21,12 +21,25 @@ package org.apache.causeway.core.metamodel.valuetypes;
 import java.time.Duration;
 import java.time.temporal.Temporal;
 
+import 
org.apache.causeway.applib.value.semantics.TemporalCharacteristicsProvider;
+
 public abstract class TemporalSemanticsAdapter<T, D extends Temporal>
-extends ValueSemanticsAdapter<T, D, Duration> {
+extends ValueSemanticsAdapter<T, D, Duration>
+implements TemporalCharacteristicsProvider {
 
     // -- ORDER RELATION
 
     protected final static Duration ALMOST_A_SECOND = 
Duration.ofNanos(999_999_999);
     protected final static Duration ALMOST_A_MILLI_SECOND = 
Duration.ofNanos(999_999);
 
+    @Override
+    public final TemporalCharacteristic getTemporalCharacteristic() {
+        return 
((TemporalCharacteristicsProvider)getDelegate()).getTemporalCharacteristic();
+    }
+
+    @Override
+    public final OffsetCharacteristic getOffsetCharacteristic() {
+        return 
((TemporalCharacteristicsProvider)getDelegate()).getOffsetCharacteristic();
+    }
+
 }
diff --git 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProviderTest.java
 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProviderTest.java
index bf9cee954c..4567b585cd 100644
--- 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProviderTest.java
+++ 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProviderTest.java
@@ -31,10 +31,10 @@ import static 
org.junit.jupiter.api.Assertions.assertNotNull;
 
 import org.apache.causeway.applib.annotation.TimePrecision;
 import org.apache.causeway.applib.locale.UserLocale;
+import 
org.apache.causeway.applib.value.semantics.TemporalCharacteristicsProvider.OffsetCharacteristic;
+import 
org.apache.causeway.applib.value.semantics.TemporalCharacteristicsProvider.TemporalCharacteristic;
 import org.apache.causeway.applib.value.semantics.TemporalValueSemantics;
 import 
org.apache.causeway.applib.value.semantics.TemporalValueSemantics.EditingFormatDirection;
-import 
org.apache.causeway.applib.value.semantics.TemporalValueSemantics.OffsetCharacteristic;
-import 
org.apache.causeway.applib.value.semantics.TemporalValueSemantics.TemporalCharacteristic;
 import 
org.apache.causeway.applib.value.semantics.TemporalValueSemantics.TemporalEditingPattern;
 import 
org.apache.causeway.applib.value.semantics.ValueSemanticsProvider.Context;
 import org.apache.causeway.core.config.CausewayConfiguration;
diff --git 
a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ScalarModel.java
 
b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ScalarModel.java
index f74d471ccd..1050cfe699 100644
--- 
a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ScalarModel.java
+++ 
b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ScalarModel.java
@@ -26,18 +26,16 @@ import org.apache.wicket.model.ChainingModel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.util.convert.IConverter;
 
-import org.springframework.util.ClassUtils;
-
 import org.apache.causeway.applib.annotation.PromptStyle;
 import org.apache.causeway.commons.collections.Can;
 import org.apache.causeway.commons.functional.Either;
-import org.apache.causeway.commons.internal.assertions._Assert;
 import org.apache.causeway.commons.internal.base._NullSafe;
 import org.apache.causeway.core.metamodel.commons.ViewOrEditMode;
 import org.apache.causeway.core.metamodel.interactions.managed.ManagedValue;
 import org.apache.causeway.core.metamodel.object.ManagedObject;
 import org.apache.causeway.core.metamodel.object.ManagedObjects;
 import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
+import org.apache.causeway.core.metamodel.spec.feature.ObjectFeature;
 import org.apache.causeway.core.metamodel.util.Facets;
 import org.apache.causeway.viewer.commons.model.hints.HasRenderingHints;
 import org.apache.causeway.viewer.commons.model.hints.RenderingHint;
@@ -183,13 +181,9 @@ implements HasRenderingHints, UiScalar, 
FormExecutorContext {
     // -- CONVERSION
 
     public final <T> Optional<IConverter<T>> getConverter(final Class<T> 
requiredType) {
-
-        _Assert.assertTypeIsInstanceOf(
-                
ClassUtils.resolvePrimitiveIfNecessary(getMetaModel().getElementType().getCorrespondingClass()),
-                requiredType);
-
+        final ObjectFeature propOrParam = getMetaModel();
         return Optional.of(
-                new ConverterBasedOnValueSemantics<>(getMetaModel(), 
getViewOrEditMode()));
+                new ConverterBasedOnValueSemantics<>(requiredType, 
propOrParam, getViewOrEditMode()));
     }
 
     // -- PREDICATES
diff --git 
a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/value/ConverterBasedOnValueSemantics.java
 
b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/value/ConverterBasedOnValueSemantics.java
index 96577f5abf..269ab6319b 100644
--- 
a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/value/ConverterBasedOnValueSemantics.java
+++ 
b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/value/ConverterBasedOnValueSemantics.java
@@ -23,6 +23,10 @@ import java.util.Locale;
 import org.apache.wicket.util.convert.ConversionException;
 import org.apache.wicket.util.convert.IConverter;
 
+import org.springframework.lang.Nullable;
+import org.springframework.util.ClassUtils;
+
+import org.apache.causeway.commons.internal.assertions._Assert;
 import org.apache.causeway.commons.internal.base._Casts;
 import org.apache.causeway.commons.internal.exceptions._Exceptions;
 import org.apache.causeway.core.metamodel.commons.ViewOrEditMode;
@@ -38,10 +42,22 @@ implements IConverter<T> {
 
     private static final long serialVersionUID = 1L;
 
+    public final Class<T> type;
+    public final Class<?> resolvedType;
+
     public ConverterBasedOnValueSemantics(
+            final @NonNull Class<T> type,
             final @NonNull ObjectFeature propOrParam,
             final @NonNull ViewOrEditMode scalarRepresentation) {
         super(propOrParam, scalarRepresentation);
+        this.type = type;
+        this.resolvedType = 
ClassUtils.resolvePrimitiveIfNecessary(propOrParam.getElementType().getCorrespondingClass());
+        _Assert.assertTypeIsInstanceOf(resolvedType, type);
+    }
+
+    public final boolean canHandle(final @Nullable Class<?> aType) {
+        return aType!=null
+                && 
resolvedType.isAssignableFrom(ClassUtils.resolvePrimitiveIfNecessary(aType));
     }
 
     /**
diff --git 
a/viewers/wicket/ui-test/src/test/java/org/apache/causeway/viewer/wicket/ui/test/components/scalars/ConverterTester.java
 
b/viewers/wicket/ui-test/src/test/java/org/apache/causeway/viewer/wicket/ui/test/components/scalars/ConverterTester.java
index e0fe603dc2..9d7c7f20bd 100644
--- 
a/viewers/wicket/ui-test/src/test/java/org/apache/causeway/viewer/wicket/ui/test/components/scalars/ConverterTester.java
+++ 
b/viewers/wicket/ui-test/src/test/java/org/apache/causeway/viewer/wicket/ui/test/components/scalars/ConverterTester.java
@@ -117,7 +117,8 @@ public class ConverterTester<T extends Serializable> {
             final ViewOrEditMode representation) {
         val customerSpec = 
mmc.getSpecificationLoader().specForTypeElseFail(type);
         val prop = customerSpec.getPropertyElseFail("value");
-        return new ConverterBasedOnValueSemantics<>(prop, representation);
+        var propType = (Class<T>) 
prop.getElementType().getCorrespondingClass();
+        return new ConverterBasedOnValueSemantics<T>(propType, prop, 
representation);
     }
 
     public void runWithInteraction(final @NonNull ThrowingRunnable runnable) {
diff --git 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldWithTemporalPicker.java
 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldWithTemporalPicker.java
index 14f80906de..0b897d795a 100644
--- 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldWithTemporalPicker.java
+++ 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldWithTemporalPicker.java
@@ -29,10 +29,8 @@ import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
 import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.model.PropertyModel;
 
-import org.apache.causeway.applib.value.semantics.TemporalValueSemantics;
-import 
org.apache.causeway.applib.value.semantics.TemporalValueSemantics.OffsetCharacteristic;
-import org.apache.causeway.commons.internal.base._Casts;
-import org.apache.causeway.commons.internal.exceptions._Exceptions;
+import 
org.apache.causeway.applib.value.semantics.TemporalCharacteristicsProvider;
+import 
org.apache.causeway.applib.value.semantics.TemporalCharacteristicsProvider.OffsetCharacteristic;
 import org.apache.causeway.core.metamodel.util.Facets;
 import org.apache.causeway.viewer.wicket.model.models.ScalarModel;
 import 
org.apache.causeway.viewer.wicket.model.value.ConverterBasedOnValueSemantics;
@@ -70,7 +68,7 @@ extends ScalarPanelTextFieldWithValueSemantics<T>  {
 
         this.temporalDecomposition = TemporalDecomposition.create(type,
                 scalarModel,
-                temporalValueSemantics(),
+                offsetCharacteristic(),
                 (ConverterBasedOnValueSemantics<T>)converterElseFail());
 
         val textField = new TextFieldWithDateTimePicker<T>(
@@ -95,13 +93,13 @@ extends ScalarPanelTextFieldWithValueSemantics<T>  {
         case OFFSET:
             Wkt.dropDownChoiceWithAjaxUpdateAdd(container, "timeoffset",
                     new PropertyModel<ZoneOffset>(temporalDecomposition, 
"zoneOffset"),
-                    temporalValueSemantics().getAvailableOffsets())
+                    temporalAndOffsetCharacteristics().getAvailableOffsets())
                 .setRequired(true);
             break;
         case ZONED:
             Wkt.dropDownChoiceWithAjaxUpdateAdd(container, "timezone",
                     new PropertyModel<ZoneId>(temporalDecomposition, "zoneId"),
-                    temporalValueSemantics().getAvailableZoneIds())
+                    temporalAndOffsetCharacteristics().getAvailableZoneIds())
                 .setRequired(true);
             break;
         case LOCAL:
@@ -133,14 +131,12 @@ extends ScalarPanelTextFieldWithValueSemantics<T>  {
 
     // -- HELPER
 
-    private TemporalValueSemantics<T> temporalValueSemantics() {
-        return 
_Casts.uncheckedCast(Facets.valueTemporalSemantics(scalarModel().getElementType())
-                .orElseThrow(()->_Exceptions.illegalState("no (temporal) value 
semantics found for %s",
-                        scalarModel().getElementType())));
+    private TemporalCharacteristicsProvider temporalAndOffsetCharacteristics() 
{
+        return 
Facets.valueTemporalAndOffsetCharacteristicsElseFail(scalarModel().getElementType());
     }
 
     private OffsetCharacteristic offsetCharacteristic() {
-        return temporalValueSemantics().getOffsetCharacteristic();
+        return temporalAndOffsetCharacteristics().getOffsetCharacteristic();
     }
 
     private <X> TextField<X> installUpdateNotifier(final TextField<X> 
textField) {
diff --git 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/scalars/datepicker/TemporalDecomposition.java
 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/scalars/datepicker/TemporalDecomposition.java
index fc85f5a21c..f9bde9c49b 100644
--- 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/scalars/datepicker/TemporalDecomposition.java
+++ 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/scalars/datepicker/TemporalDecomposition.java
@@ -29,8 +29,8 @@ import java.util.Locale;
 import org.apache.wicket.util.convert.ConversionException;
 import org.apache.wicket.util.convert.IConverter;
 
-import org.apache.causeway.applib.value.semantics.TemporalValueSemantics;
-import 
org.apache.causeway.applib.value.semantics.TemporalValueSemantics.OffsetCharacteristic;
+import 
org.apache.causeway.applib.value.semantics.TemporalCharacteristicsProvider.OffsetCharacteristic;
+import org.apache.causeway.commons.internal.assertions._Assert;
 import org.apache.causeway.commons.internal.base._Strings;
 import org.apache.causeway.commons.internal.base._Temporals;
 import org.apache.causeway.core.metamodel.commons.ViewOrEditMode;
@@ -50,15 +50,17 @@ import lombok.Setter;
  * based on existing widgets, that do not support zone or offset information.
  */
 @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
-public class TemporalDecomposition<T extends Temporal> implements 
IConverter<T> {
+public class TemporalDecomposition<T> implements IConverter<T> {
     private static final long serialVersionUID = 1L;
 
     public static <T extends Temporal> TemporalDecomposition<T> create(final 
Class<T> type,
             final ScalarModel scalarModel,
-            final TemporalValueSemantics<T> temporalValueSemantics,
+            final OffsetCharacteristic offsetCharacteristic,
             final ConverterBasedOnValueSemantics<T> fullConverter) {
 
-        var needsDecomposition = 
!temporalValueSemantics.getOffsetCharacteristic().isLocal()
+        _Assert.assertTrue(fullConverter.canHandle(type));
+
+        var needsDecomposition = !offsetCharacteristic.isLocal()
                 && scalarModel.getViewOrEditMode().isEditing();
 
         var baseEditingPattern = fullConverter.getEditingPattern();
@@ -66,7 +68,7 @@ public class TemporalDecomposition<T extends Temporal> 
implements IConverter<T>
             ? stripZoneSuffixFrom(baseEditingPattern)
             : baseEditingPattern;
 
-        var tempDecomp = new TemporalDecomposition<>(type, 
temporalValueSemantics, fullConverter,
+        var tempDecomp = new TemporalDecomposition<>(type, 
offsetCharacteristic, fullConverter,
                 scalarModel.getViewOrEditMode(),
                 editingPattern);
 
@@ -77,7 +79,7 @@ public class TemporalDecomposition<T extends Temporal> 
implements IConverter<T>
     }
 
     private final @NonNull Class<T> type;
-    private final @NonNull TemporalValueSemantics<T> temporalValueSemantics;
+    private final OffsetCharacteristic offsetCharacteristic;
     private final @NonNull ConverterBasedOnValueSemantics<T> fullConverter;
     private final @NonNull ViewOrEditMode viewOrEditMode;
 
@@ -85,6 +87,7 @@ public class TemporalDecomposition<T extends Temporal> 
implements IConverter<T>
     private final String editingPattern;
 
     private void initFrom(final ManagedValue proposedValue) {
+        //TODO[CAUSEWAY-3489] handle non java.time.Temporal values also
         var temporalValue = 
MmUnwrapUtils.single(proposedValue.getValue().getValue());
         if(temporalValue instanceof ZonedDateTime) {
             var zonedDateTime = (ZonedDateTime) temporalValue;
@@ -99,6 +102,8 @@ public class TemporalDecomposition<T extends Temporal> 
implements IConverter<T>
         //TODO[CAUSEWAY-3489] zone/offset info on new temporal value should be 
set to current user's info from session
     }
 
+    // -- CONVERTER
+
     @Override
     public T convertToObject(final String noZoneValue, final Locale locale) 
throws ConversionException {
         var fullTemporalString = noZoneValue + getZoneOrOffsetSuffix();
@@ -111,12 +116,8 @@ public class TemporalDecomposition<T extends Temporal> 
implements IConverter<T>
 
     // -- SPECIALIZATION
 
-    private OffsetCharacteristic offsetCharacteristic() {
-        return temporalValueSemantics.getOffsetCharacteristic();
-    }
-
     private String getZoneOrOffsetSuffix() {
-        switch (offsetCharacteristic()) {
+        switch (offsetCharacteristic) {
         case OFFSET:
             return " " + _Temporals.formatZoneId(zoneOffset==null
                     ? ZoneOffset.UTC

Reply via email to