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.sql.Timestamp;
7 import java.time.Instant;
8 import java.time.YearMonth;
9 import java.time.ZoneId;
10 import java.util.Date;
11 import java.util.Objects;
12
13 /**
14  * @author Vlad Mihalcea
15  */

16 public class YearMonthTypeDescriptor
17         extends AbstractTypeDescriptor<YearMonth> {
18
19     public static final YearMonthTypeDescriptor INSTANCE = new YearMonthTypeDescriptor();
20
21     public YearMonthTypeDescriptor() {
22         super(YearMonth.class);
23     }
24
25     @Override
26     public boolean areEqual(YearMonth one, YearMonth another) {
27         return Objects.equals(one, another);
28     }
29
30     @Override
31     public String toString(YearMonth value) {
32         return value.toString();
33     }
34
35     @Override
36     public YearMonth fromString(String string) {
37         return YearMonth.parse(string);
38     }
39
40     @SuppressWarnings({"unchecked"})
41     @Override
42     public <X> X unwrap(YearMonth value, Class<X> type, WrapperOptions options) {
43         if (value == null) {
44             return null;
45         }
46         if (String.class.isAssignableFrom(type)) {
47             return (X) toString(value);
48         }
49         if (Number.class.isAssignableFrom(type)) {
50             Integer numericValue = (value.getYear() * 100) + value.getMonth().getValue();
51             return (X) (numericValue);
52         }
53         if (Timestamp.class.isAssignableFrom(type)) {
54             return (X) java.sql.Timestamp.valueOf(value.atDay(1).atStartOfDay());
55         }
56         if (Date.class.isAssignableFrom(type)) {
57             return (X) java.sql.Date.valueOf(value.atDay(1));
58         }
59         throw unknownUnwrap(type);
60     }
61
62     @Override
63     public <X> YearMonth wrap(X value, WrapperOptions options) {
64         if (value == null) {
65             return null;
66         }
67         if (value instanceof String) {
68             return fromString((String) value);
69         }
70         if (value instanceof Number) {
71             int numericValue = ((Number) (value)).intValue();
72             if(numericValue > 0) {
73                 int year = numericValue / 100;
74                 int month = numericValue % 100;
75                 return YearMonth.of(year, month);
76             } else {
77                 return null;
78             }
79         }
80         if (value instanceof Date) {
81             Date date = (Date) value;
82             return YearMonth.from(Instant.ofEpochMilli(date.getTime())
83                     .atZone(ZoneId.systemDefault())
84                     .toLocalDate());
85         }
86         throw unknownWrap(value.getClass());
87     }
88 }
89