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 293328ab96 ISIS-3085: adds logic for TO_LOCAL_TIMEZONE rendering mode
293328ab96 is described below

commit 293328ab96ebd52100e38a2c2f9d2e540e7e3a04
Author: andi-huber <[email protected]>
AuthorDate: Fri Jul 22 11:29:42 2022 +0200

    ISIS-3085: adds logic for TO_LOCAL_TIMEZONE rendering mode
---
 .../applib/annotation/TimeZoneTranslation.java     | 44 +++++++++++++
 .../isis/applib/annotation/ValueSemantics.java     | 12 ++++
 .../valuesemantics/temporal/BadgeRenderer.java     | 54 +++++++++++++++
 .../temporal/TemporalValueSemanticsProvider.java   | 77 ++++++++++++++--------
 4 files changed, 159 insertions(+), 28 deletions(-)

diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/annotation/TimeZoneTranslation.java
 
b/api/applib/src/main/java/org/apache/isis/applib/annotation/TimeZoneTranslation.java
new file mode 100644
index 0000000000..5178c39569
--- /dev/null
+++ 
b/api/applib/src/main/java/org/apache/isis/applib/annotation/TimeZoneTranslation.java
@@ -0,0 +1,44 @@
+/*
+ *  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.applib.annotation;
+
+/**
+ * Rendering mode for temporals (<i>time instants</i>) with time-zone or 
time-offset information.
+ *
+ * @since 2.0 {@index}
+ */
+public enum TimeZoneTranslation {
+
+    UNSPECIFIED,
+
+    /**
+     * Renders temporals(<i>time instants</i>) - that have time-zone or 
time-offset information
+     * - transformed to the user's local/current time-zone,
+     * optionally with a tooltip providing information on the originating (non 
transformed) <i>time instant</i>.
+     */
+    TO_LOCAL_TIMEZONE,
+
+    /**
+     * Renders temporals (<i>time instants</i>) - that have time-zone or 
time-offset information - as is,
+     * optionally with a tooltip providing information on the <i>time 
instant</i>
+     * as transformed to the user's local/current time-zone.
+     */
+    NONE;
+
+}
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/annotation/ValueSemantics.java
 
b/api/applib/src/main/java/org/apache/isis/applib/annotation/ValueSemantics.java
index 5c956ac555..b99be4e732 100644
--- 
a/api/applib/src/main/java/org/apache/isis/applib/annotation/ValueSemantics.java
+++ 
b/api/applib/src/main/java/org/apache/isis/applib/annotation/ValueSemantics.java
@@ -129,6 +129,18 @@ public @interface ValueSemantics {
     TimePrecision timePrecision()
         default TimePrecision.SECOND;
 
+
+    /**
+     * 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.<br>
+     * default = {@link TimeZoneTranslation#TO_LOCAL_TIMEZONE}
+     * @see TimeZoneTranslation
+     */
+    TimeZoneTranslation timeZoneTranslation()
+        default TimeZoneTranslation.TO_LOCAL_TIMEZONE;
+
     /**
      * eg. &#64;ValueSemantics(dateRenderAdjustDays = 
ValueSemantics.AS_DAY_BEFORE)
      */
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/BadgeRenderer.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/BadgeRenderer.java
new file mode 100644
index 0000000000..ef662ae5a6
--- /dev/null
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/BadgeRenderer.java
@@ -0,0 +1,54 @@
+/*
+ *  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.valuesemantics.temporal;
+
+import java.util.function.Supplier;
+
+/**
+ * Provides html rendering for temporals with time-zone or time-offset 
information.
+ *
+ * @since 2.0
+ */
+public interface BadgeRenderer {
+
+    String render(String text, Supplier<String> tooltipProvider);
+
+    // -- FACTORIES
+
+    /**
+     * non-html, text only; ignoring tooltip
+     */
+    public static BadgeRenderer textual() {
+        return (text, tooltipProvider)->text;
+    }
+
+    /**
+     * Depends on presence of <i>Bootstrap</i>.
+     */
+    public static BadgeRenderer bootstrapBadgeWithTooltip() {
+        return (text, tooltipProvider)->String.format("<span "
+                + "class=\"badge bg-secondary\" "
+                + "data-bs-container=\"body\" "
+                + "data-bs-toggle=\"tooltip\" "
+                + "title=\"%s\">"
+                + "%s"
+                + "</span>", tooltipProvider.get(), text);
+    }
+
+}
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 ed426a78e8..a095f66c51 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
@@ -31,7 +31,6 @@ import java.time.temporal.Temporal;
 import java.time.temporal.TemporalQuery;
 import java.util.Optional;
 import java.util.function.BiFunction;
-import java.util.function.BinaryOperator;
 import java.util.function.Function;
 import java.util.function.UnaryOperator;
 
@@ -40,6 +39,7 @@ import javax.inject.Inject;
 import org.springframework.lang.Nullable;
 
 import org.apache.isis.applib.annotation.TimePrecision;
+import org.apache.isis.applib.annotation.TimeZoneTranslation;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
 import org.apache.isis.applib.util.schema.CommonDtoUtils;
 import org.apache.isis.applib.value.semantics.TemporalValueSemantics;
@@ -150,27 +150,14 @@ implements TemporalValueSemantics<T> {
     public final String titlePresentation(
             final ValueSemanticsProvider.Context context,
             final T value) {
-        return renderTitle(value, getRenderingFormatter(context, (text, 
tooltip)->text));
+        return renderTitle(value, getRenderingFormatter(context, 
BadgeRenderer.textual()));
     }
 
     @Override
     public final String htmlPresentation(
             final ValueSemanticsProvider.Context context,
             final T value) {
-        return renderHtml(value, getRenderingFormatter(context, 
this::toBootstrapBadgeWithTooltip));
-    }
-
-    /**
-     * @apiNote Ideally this logic would move to Wicket Viewer, as it depends 
on presence of <i>Bootstrap</i>.
-     */
-    private String toBootstrapBadgeWithTooltip(final String text, final String 
tooltip) {
-        return String.format("<span "
-                + "class=\"badge bg-secondary\" "
-                + "data-bs-container=\"body\" "
-                + "data-bs-toggle=\"tooltip\" "
-                + "title=\"%s\">"
-                + "%s"
-                + "</span>", tooltip, text);
+        return renderHtml(value, getRenderingFormatter(context, 
BadgeRenderer.bootstrapBadgeWithTooltip()));
     }
 
     // -- PARSER
@@ -213,7 +200,7 @@ implements TemporalValueSemantics<T> {
      */
     protected Function<T, String> getRenderingFormatter(
             final ValueSemanticsProvider.Context context,
-            final BinaryOperator<String> timeZoneDecorator) {
+            final BadgeRenderer badgeRenderer) {
 
         val dateAndTimeFormatStyle = DateAndTimeFormatStyle.forContext(mmc, 
context);
 
@@ -225,20 +212,54 @@ implements TemporalValueSemantics<T> {
                         dateAndTimeFormatStyle.getTimeFormatStyle());
 
                 final var temporalZoneOnlyRenderingFormat = 
getTemporalZoneOnlyRenderingFormat(
-                        context, temporalCharacteristic, offsetCharacteristic);
+                        context, temporalCharacteristic, 
offsetCharacteristic).orElse(null);
 
                 final var sb = new StringBuffer();
 
-                sb.append(temporalNoZoneRenderingFormat.format(time));
-
-                temporalZoneOnlyRenderingFormat
-                .ifPresent(zoneOnlyFormat->{
-                    sb.append(' ').append(timeZoneDecorator.apply(
-                            zoneOnlyFormat.format(time),
-                            translate("your local time: ")
-                                + " "
-                                + 
temporalNoZoneRenderingFormat.format(toLocalTime(context, time))));
-                });
+                //FIXME[ISIS-3085] use as provided via ValueSemantics 
annotation ...
+                final var timeZoneTranslation = 
TimeZoneTranslation.TO_LOCAL_TIMEZONE;
+
+                final var asLocalTime = toLocalTime(context, time);
+
+                switch (timeZoneTranslation) {
+                case TO_LOCAL_TIMEZONE:
+                    if(offsetCharacteristic.isLocal()) {
+                        // start rendering with the time as is (no offset/zone 
info)
+                        sb.append(temporalNoZoneRenderingFormat.format(time));
+                    } else {
+                        // start rendering with the (to-local) translated time 
(no offset/zone info)
+                        
sb.append(temporalNoZoneRenderingFormat.format(asLocalTime));
+
+                        // we have offset/zone information, so we append it 
(properly formatted) ...
+                        sb.append(' ');
+
+                        sb.append(badgeRenderer.render(
+                                translate("local"),
+                                ()->translate("time instant")
+                                    + ": "
+                                    + 
temporalNoZoneRenderingFormat.format(time)
+                                    + " "
+                                    + 
temporalZoneOnlyRenderingFormat.format(time)));
+
+                    }
+                    break;
+                case NONE:
+                default:
+                    // start rendering with the time as is (no offset/zone 
info)
+                    sb.append(temporalNoZoneRenderingFormat.format(time));
+
+                    if(!offsetCharacteristic.isLocal()) {
+                        // we have offset/zone information, so we append it 
(properly formatted) ...
+                        sb.append(' ');
+
+                        sb.append(badgeRenderer.render(
+                                temporalZoneOnlyRenderingFormat.format(time),
+                                ()->translate("your local time")
+                                    + ": "
+                                    + 
temporalNoZoneRenderingFormat.format(asLocalTime)));
+                    }
+                    break;
+                }
 
                 return sb.toString();
         };

Reply via email to