1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.core.metapath.item.atomic.impl;
7   
8   import java.time.Duration;
9   import java.time.ZoneOffset;
10  
11  import dev.metaschema.core.datatype.adapter.DayTimeAdapter;
12  import dev.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider;
13  import dev.metaschema.core.metapath.function.DateTimeFunctionException;
14  import dev.metaschema.core.metapath.impl.AbstractMapKey;
15  import dev.metaschema.core.metapath.item.atomic.IDayTimeDurationItem;
16  import dev.metaschema.core.metapath.item.function.IMapKey;
17  import dev.metaschema.core.metapath.item.function.IOpaqueMapKey;
18  import dev.metaschema.core.util.ObjectUtils;
19  import edu.umd.cs.findbugs.annotations.NonNull;
20  
21  /**
22   * An implementation of a Metapath atomic item containing a duration data value
23   * in days, hours, and seconds.
24   */
25  public class DayTimeDurationItemImpl
26      extends AbstractDurationItem<Duration>
27      implements IDayTimeDurationItem {
28    private static final long MIN_OFFSET_SECONDS = -50_400; // -14 hours in seconds
29    private static final long MAX_OFFSET_SECONDS = 50_400; // 14 hours in seconds
30  
31    /**
32     * Construct a new item with the provided {@code value}.
33     *
34     * @param value
35     *          the value to wrap
36     */
37    public DayTimeDurationItemImpl(@NonNull Duration value) {
38      super(value);
39    }
40  
41    @Override
42    public Duration asDuration() {
43      return getValue();
44    }
45  
46    @Override
47    public ZoneOffset asZoneOffset() {
48      Duration duration = asDuration();
49      long seconds = duration.toSeconds();
50      if (seconds < MIN_OFFSET_SECONDS || seconds > MAX_OFFSET_SECONDS) {
51        throw new DateTimeFunctionException(
52            DateTimeFunctionException.INVALID_TIME_ZONE_VALUE_ERROR,
53            String.format("The duration '%s' must be >= -PT14H and <= PT13H.", duration.toString()));
54      }
55      return ObjectUtils.notNull(ZoneOffset.ofTotalSeconds((int) seconds));
56    }
57  
58    @Override
59    public DayTimeAdapter getJavaTypeAdapter() {
60      return MetaschemaDataTypeProvider.DAY_TIME_DURATION;
61    }
62  
63    @Override
64    public int hashCode() {
65      return asDuration().hashCode();
66    }
67  
68    @Override
69    public boolean equals(Object obj) {
70      return this == obj
71          || obj instanceof IDayTimeDurationItem && compareTo((IDayTimeDurationItem) obj) == 0;
72    }
73  
74    @Override
75    public IMapKey asMapKey() {
76      return new MapKey();
77    }
78  
79    private final class MapKey
80        extends AbstractMapKey
81        implements IOpaqueMapKey {
82      @Override
83      public IDayTimeDurationItem getKey() {
84        return DayTimeDurationItemImpl.this;
85      }
86    }
87  }