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/07/24 14:54:26 UTC

[isis] branch master updated: ISIS-3085: introduces TimeZoneTranslationFacet

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 273efa05fc ISIS-3085: introduces TimeZoneTranslationFacet
273efa05fc is described below

commit 273efa05fc8a3058e906b44ce9875bac6dcebec3
Author: andi-huber <ah...@apache.org>
AuthorDate: Sun Jul 24 16:54:20 2022 +0200

    ISIS-3085: introduces TimeZoneTranslationFacet
    
    - also adds test cases
---
 .../temporalformat/TimeZoneTranslationFacet.java   | 41 ++++++++++++
 .../TimeZoneTranslationFacetAbstract.java          | 73 ++++++++++++++++++++++
 ...anslationFacetFromValueSemanticsAnnotation.java | 47 ++++++++++++++
 .../ValueSemanticsAnnotationFacetFactory.java      |  4 ++
 .../temporal/TemporalValueSemanticsProvider.java   | 22 ++++---
 .../ValueSemanticsAnnotationFacetFactoryTest.java  | 38 ++++++++++-
 6 files changed, 214 insertions(+), 11 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/temporalformat/TimeZoneTranslationFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/temporalformat/TimeZoneTranslationFacet.java
new file mode 100644
index 0000000000..3ec8fc7712
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/temporalformat/TimeZoneTranslationFacet.java
@@ -0,0 +1,41 @@
+/*
+ *  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.isis.core.metamodel.facets.objectvalue.temporalformat;
+
+import org.apache.isis.applib.annotation.TimeZoneTranslation;
+import org.apache.isis.applib.annotation.ValueSemantics;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+
+/**
+ * If associated with a temporal value,
+ * that has time-zone or time-offset information,
+ * the rendering mode, as to whether to transform the rendered value
+ * to the user's local/current time-zone or not.
+ *
+ * @see ValueSemantics#timeZoneTranslation()
+ */
+public interface TimeZoneTranslationFacet
+extends Facet {
+
+    /**
+     * As provided by {@link ValueSemantics#timeZoneTranslation()}.
+     */
+    TimeZoneTranslation getTimeZoneTranslation();
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/temporalformat/TimeZoneTranslationFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/temporalformat/TimeZoneTranslationFacetAbstract.java
new file mode 100644
index 0000000000..293d4ee39e
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/objectvalue/temporalformat/TimeZoneTranslationFacetAbstract.java
@@ -0,0 +1,73 @@
+/*
+ *  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.isis.core.metamodel.facets.objectvalue.temporalformat;
+
+import java.util.Objects;
+import java.util.function.BiConsumer;
+
+import org.apache.isis.applib.annotation.TimeZoneTranslation;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+
+import lombok.Getter;
+import lombok.NonNull;
+
+public abstract class TimeZoneTranslationFacetAbstract
+extends FacetAbstract
+implements TimeZoneTranslationFacet {
+
+    private static final Class<? extends Facet> type() {
+        return TimeZoneTranslationFacet.class;
+    }
+
+    @Getter(onMethod_ = {@Override})
+    private final @NonNull TimeZoneTranslation timeZoneTranslation;
+
+    protected TimeZoneTranslationFacetAbstract(
+            final TimeZoneTranslation timeZoneTranslation,
+            final FacetHolder holder) {
+        super(type(), holder);
+        this.timeZoneTranslation = timeZoneTranslation;
+    }
+
+    protected TimeZoneTranslationFacetAbstract(
+            final TimeZoneTranslation timeZoneTranslation,
+            final FacetHolder holder,
+            final Facet.Precedence precedence) {
+        super(type(), holder, precedence);
+        this.timeZoneTranslation = timeZoneTranslation;
+    }
+
+    @Override
+    public boolean semanticEquals(@NonNull final Facet other) {
+        return other instanceof TimeZoneTranslationFacet
+                ? Objects.equals(
+                        this.getTimeZoneTranslation(),
+                        ((TimeZoneTranslationFacet)other).getTimeZoneTranslation())
+                : false;
+    }
+
+    @Override
+    public void visitAttributes(final BiConsumer<String, Object> visitor) {
+        super.visitAttributes(visitor);
+        visitor.accept("timeZoneTranslation", timeZoneTranslation.name());
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/semantics/TimeZoneTranslationFacetFromValueSemanticsAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/semantics/TimeZoneTranslationFacetFromValueSemanticsAnnotation.java
new file mode 100644
index 0000000000..e1b198c1de
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/semantics/TimeZoneTranslationFacetFromValueSemanticsAnnotation.java
@@ -0,0 +1,47 @@
+/*
+ *  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.isis.core.metamodel.facets.value.semantics;
+
+import java.util.Optional;
+
+import org.apache.isis.applib.annotation.TimeZoneTranslation;
+import org.apache.isis.applib.annotation.ValueSemantics;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.objectvalue.temporalformat.TimeZoneTranslationFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.temporalformat.TimeZoneTranslationFacetAbstract;
+
+public class TimeZoneTranslationFacetFromValueSemanticsAnnotation
+extends TimeZoneTranslationFacetAbstract {
+
+    public static Optional<TimeZoneTranslationFacet> create(
+            final Optional<ValueSemantics> valueSemanticsIfAny,
+            final FacetHolder holder) {
+
+        return valueSemanticsIfAny
+        .map(ValueSemantics::timeZoneTranslation)
+        .map(timeZoneTranslation->
+            new TimeZoneTranslationFacetFromValueSemanticsAnnotation(timeZoneTranslation, holder));
+   }
+
+   private TimeZoneTranslationFacetFromValueSemanticsAnnotation(
+           final TimeZoneTranslation timeZoneTranslation, final FacetHolder holder) {
+       super(timeZoneTranslation, holder);
+   }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/semantics/ValueSemanticsAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/semantics/ValueSemanticsAnnotationFacetFactory.java
index 9895c7cfda..55eaf6cdb2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/semantics/ValueSemanticsAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/semantics/ValueSemanticsAnnotationFacetFactory.java
@@ -143,6 +143,10 @@ extends FacetFactoryAbstract {
         addFacetIfPresent(
                 DateRenderAdjustFacetFromValueSemanticsAnnotation
                 .create(valueSemanticsIfAny, facetHolder));
+
+        addFacetIfPresent(
+                TimeZoneTranslationFacetFromValueSemanticsAnnotation
+                .create(valueSemanticsIfAny, facetHolder));
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
index a095f66c51..2463d5b59e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
@@ -52,6 +52,7 @@ import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facets.objectvalue.temporalformat.DateFormatStyleFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.temporalformat.TimeFormatPrecisionFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.temporalformat.TimeFormatStyleFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.temporalformat.TimeZoneTranslationFacet;
 
 import lombok.Getter;
 import lombok.NonNull;
@@ -214,13 +215,12 @@ implements TemporalValueSemantics<T> {
                 final var temporalZoneOnlyRenderingFormat = getTemporalZoneOnlyRenderingFormat(
                         context, temporalCharacteristic, offsetCharacteristic).orElse(null);
 
-                final var sb = new StringBuffer();
-
-                //FIXME[ISIS-3085] use as provided via ValueSemantics annotation ...
-                final var timeZoneTranslation = TimeZoneTranslation.TO_LOCAL_TIMEZONE;
+                final var timeZoneTranslation = dateAndTimeFormatStyle.getTimeZoneTranslation();
 
                 final var asLocalTime = toLocalTime(context, time);
 
+                final var sb = new StringBuffer();
+
                 switch (timeZoneTranslation) {
                 case TO_LOCAL_TIMEZONE:
                     if(offsetCharacteristic.isLocal()) {
@@ -337,9 +337,10 @@ implements TemporalValueSemantics<T> {
 
     @Value(staticConstructor = "of")
     static class DateAndTimeFormatStyle {
-        @Nullable FormatStyle dateFormatStyle;
-        @Nullable FormatStyle timeFormatStyle;
-        @Nullable TimePrecision timePrecision;
+        @NonNull FormatStyle dateFormatStyle;
+        @NonNull FormatStyle timeFormatStyle;
+        @NonNull TimePrecision timePrecision;
+        @NonNull TimeZoneTranslation timeZoneTranslation;
 
         static DateAndTimeFormatStyle forContext(
                 final @Nullable MetaModelContext mmc, // nullable .. JUnit support
@@ -367,7 +368,12 @@ implements TemporalValueSemantics<T> {
                     .map(TimeFormatPrecisionFacet::getTimePrecision)
                     .orElse(TimePrecision.SECOND);
 
-            return of(dateFormatStyle, timeFormatStyle, timePrecision);
+            val timeZoneTranslation = featureIfAny
+                    .flatMap(feature->feature.lookupFacet(TimeZoneTranslationFacet.class))
+                    .map(TimeZoneTranslationFacet::getTimeZoneTranslation)
+                    .orElse(TimeZoneTranslation.TO_LOCAL_TIMEZONE);
+
+            return of(dateFormatStyle, timeFormatStyle, timePrecision, timeZoneTranslation);
         }
 
     }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/semantics/ValueSemanticsAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/semantics/ValueSemanticsAnnotationFacetFactoryTest.java
index 980ec63a4c..2e426ddfa6 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/semantics/ValueSemanticsAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/value/semantics/ValueSemanticsAnnotationFacetFactoryTest.java
@@ -22,9 +22,7 @@ import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.format.FormatStyle;
 
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
+import org.apache.isis.applib.annotation.TimeZoneTranslation;
 import org.apache.isis.applib.annotation.ValueSemantics;
 import org.apache.isis.commons.internal._Constants;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -37,6 +35,10 @@ import org.apache.isis.core.metamodel.facets.objectvalue.digits.MinFractionalDig
 import org.apache.isis.core.metamodel.facets.objectvalue.digits.MinIntegerDigitsFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.temporalformat.DateFormatStyleFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.temporalformat.TimeFormatStyleFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.temporalformat.TimeZoneTranslationFacet;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
 
 @SuppressWarnings("unused")
 public class ValueSemanticsAnnotationFacetFactoryTest
@@ -260,6 +262,27 @@ extends AbstractFacetFactoryTest {
         assertDateRenderAdjustDays(facetedMethod, -1);
     }
 
+    public void testTimeZoneTranslationPickedUpOnProperty() {
+        // given
+        class Order {
+            @ValueSemantics(timeZoneTranslation = TimeZoneTranslation.NONE)
+            public LocalDateTime getDateTimeA() { return null; }
+
+            @ValueSemantics(timeZoneTranslation = TimeZoneTranslation.TO_LOCAL_TIMEZONE)
+            public LocalDateTime getDateTimeB() { return null; }
+
+        }
+        // when
+        processMethod(newFacetFactory(), Order.class, "getDateTimeA", _Constants.emptyClasses);
+        // then
+        assertTimeZoneTranslation(facetedMethod, TimeZoneTranslation.NONE);
+
+        // when
+        processMethod(newFacetFactory(), Order.class, "getDateTimeB", _Constants.emptyClasses);
+        // then
+        assertTimeZoneTranslation(facetedMethod, TimeZoneTranslation.TO_LOCAL_TIMEZONE);
+    }
+
     public void testDateFormatStylePickedUpOnProperty() {
         // given
         class Order {
@@ -372,4 +395,13 @@ extends AbstractFacetFactoryTest {
         assertThat(facet.getTimeFormatStyle(), is(formatStyle));
     }
 
+    private void assertTimeZoneTranslation(
+            final FacetedMethod facetedMethod, final TimeZoneTranslation timeZoneTranslation) {
+        final TimeZoneTranslationFacet facet = facetedMethod.getFacet(TimeZoneTranslationFacet.class);
+        assertNotNull(facet);
+        assertThat(facet.getTimeZoneTranslation(), is(timeZoneTranslation));
+    }
+
+
+
 }