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
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