1 package com.vladmihalcea.hibernate.type.basic.internal;
2
3 import org.hibernate.type.descriptor.WrapperOptions;
4 import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
5
6 import java.math.BigInteger;
7 import java.time.LocalDate;
8 import java.time.Period;
9 import java.time.YearMonth;
10 import java.util.Objects;
11
12 /**
13  * @author Vlad Mihalcea
14  */

15 public class YearMonthEpochTypeDescriptor
16         extends AbstractTypeDescriptor<YearMonth> {
17
18     public static final YearMonth YEAR_MONTH_EPOCH = YearMonth.of(1970, 1);
19
20     public static final LocalDate LOCAL_DATE_EPOCH = YEAR_MONTH_EPOCH.atDay(1);
21
22     public static final YearMonthEpochTypeDescriptor INSTANCE = new YearMonthEpochTypeDescriptor();
23
24     public YearMonthEpochTypeDescriptor() {
25         super(YearMonth.class);
26     }
27
28     @Override
29     public boolean areEqual(YearMonth one, YearMonth another) {
30         return Objects.equals(one, another);
31     }
32
33     @Override
34     public String toString(YearMonth value) {
35         return value.toString();
36     }
37
38     @Override
39     public YearMonth fromString(String string) {
40         return YearMonth.parse(string);
41     }
42
43     @SuppressWarnings({"unchecked"})
44     @Override
45     public <X> X unwrap(YearMonth value, Class<X> type, WrapperOptions options) {
46         if (value == null) {
47             return null;
48         }
49         Number monthsSinceEpoch = Period.between(LOCAL_DATE_EPOCH, value.atDay(1)).toTotalMonths();
50         if (Short.class.isAssignableFrom(type)) {
51             return (X) (Short) (monthsSinceEpoch.shortValue());
52         }
53         if (Integer.class.isAssignableFrom(type)) {
54             return (X) (Integer) (monthsSinceEpoch.intValue());
55         }
56         if (Long.class.isAssignableFrom(type)) {
57             return (X) (Long) (monthsSinceEpoch.longValue());
58         }
59         if (BigInteger.class.isAssignableFrom(type)) {
60             return (X) (BigInteger.valueOf(monthsSinceEpoch.longValue()));
61         }
62         throw unknownUnwrap(type);
63     }
64
65     @Override
66     public <X> YearMonth wrap(X value, WrapperOptions options) {
67         if (value == null) {
68             return null;
69         }
70         if (value instanceof Number) {
71             return YEAR_MONTH_EPOCH.plusMonths(((Number) value).intValue());
72         }
73         throw unknownWrap(value.getClass());
74     }
75 }
76