]> git.basschouten.com Git - openhab-addons.git/blob
54c77a0f262e217b6a2374574aac2d16dff56eed
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.persistence.dynamodb.internal;
14
15 import java.math.BigDecimal;
16 import java.math.MathContext;
17 import java.time.ZonedDateTime;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21
22 import software.amazon.awssdk.enhanced.dynamodb.mapper.StaticTableSchema;
23
24 /**
25  * DynamoDBItem for items that can be serialized as DynamoDB number
26  *
27  * @author Sami Salonen - Initial contribution
28  */
29 @NonNullByDefault
30 public class DynamoDBBigDecimalItem extends AbstractDynamoDBItem<BigDecimal> {
31
32     private static Class<@Nullable BigDecimal> NULLABLE_BIGDECIMAL = (Class<@Nullable BigDecimal>) BigDecimal.class;
33
34     public static StaticTableSchema<DynamoDBBigDecimalItem> TABLE_SCHEMA_LEGACY = getBaseSchemaBuilder(
35             DynamoDBBigDecimalItem.class, true).newItemSupplier(DynamoDBBigDecimalItem::new)
36                     .addAttribute(NULLABLE_BIGDECIMAL, a -> a.name(ATTRIBUTE_NAME_ITEMSTATE_LEGACY)
37                             .getter(DynamoDBBigDecimalItem::getState).setter(DynamoDBBigDecimalItem::setState))
38                     .build();
39
40     public static StaticTableSchema<DynamoDBBigDecimalItem> TABLE_SCHEMA_NEW = getBaseSchemaBuilder(
41             DynamoDBBigDecimalItem.class, false)
42                     .newItemSupplier(DynamoDBBigDecimalItem::new)
43                     .addAttribute(NULLABLE_BIGDECIMAL,
44                             a -> a.name(ATTRIBUTE_NAME_ITEMSTATE_NUMBER).getter(DynamoDBBigDecimalItem::getState)
45                                     .setter(DynamoDBBigDecimalItem::setState))
46                     .addAttribute(NULLABLE_LONG, a -> a.name(ATTRIBUTE_NAME_EXPIRY)
47                             .getter(AbstractDynamoDBItem::getExpiryDate).setter(AbstractDynamoDBItem::setExpiry))
48                     .build();
49
50     /**
51      * We get the following error if the BigDecimal has too many digits
52      * "Attempting to store more than 38 significant digits in a Number"
53      *
54      * See "Data types" section in
55      * http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Limits.html
56      */
57     private static final int MAX_DIGITS_SUPPORTED_BY_AMAZON = 38;
58
59     public DynamoDBBigDecimalItem() {
60         this("", null, ZonedDateTime.now(), null);
61     }
62
63     public DynamoDBBigDecimalItem(String name, @Nullable BigDecimal state, ZonedDateTime time,
64             @Nullable Integer expireDays) {
65         super(name, state, time, expireDays);
66     }
67
68     @Override
69     public @Nullable BigDecimal getState() {
70         // When serializing this to the wire, we round the number in order to ensure
71         // that it is within the dynamodb limits
72         BigDecimal localState = state;
73         if (localState == null) {
74             return null;
75         }
76         return loseDigits(localState);
77     }
78
79     @Override
80     public void setState(@Nullable BigDecimal state) {
81         this.state = state;
82     }
83
84     @Override
85     public <T> T accept(DynamoDBItemVisitor<T> visitor) {
86         return visitor.visit(this);
87     }
88
89     static BigDecimal loseDigits(BigDecimal number) {
90         return number.round(new MathContext(MAX_DIGITS_SUPPORTED_BY_AMAZON));
91     }
92 }