1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.basepom.mojo.propertyhelper.definitions;
16
17 import static com.google.common.base.Preconditions.checkNotNull;
18
19 import org.basepom.mojo.propertyhelper.FieldContext;
20 import org.basepom.mojo.propertyhelper.ValueCache;
21 import org.basepom.mojo.propertyhelper.ValueProvider;
22 import org.basepom.mojo.propertyhelper.fields.DateField;
23
24 import java.io.IOException;
25 import java.time.Instant;
26 import java.time.ZoneId;
27 import java.time.ZonedDateTime;
28 import java.time.format.DateTimeFormatter;
29 import java.time.format.DateTimeParseException;
30 import java.util.Optional;
31 import java.util.StringJoiner;
32 import java.util.function.Function;
33
34 import com.google.common.annotations.VisibleForTesting;
35
36 public class DateDefinition extends FieldDefinition<ZonedDateTime> {
37
38
39
40
41 String timezone = null;
42
43
44
45
46 Long value = null;
47
48 public DateDefinition() {
49 }
50
51 @VisibleForTesting
52 DateDefinition(String id) {
53 super(id);
54 }
55
56 public ZoneId getTimezone() {
57 return Optional.ofNullable(timezone)
58 .map(ZoneId::of)
59 .orElse(ZoneId.systemDefault());
60 }
61
62 public Optional<Long> getValue() {
63 return Optional.ofNullable(value);
64 }
65
66 @Override
67 public DateField createField(FieldContext context, ValueCache valueCache) throws IOException {
68 checkNotNull(context, "context is null");
69 checkNotNull(valueCache, "valueCache is null");
70
71 check();
72
73 final ValueProvider dateValue = valueCache.getValueProvider(this);
74 return new DateField(this, dateValue, context);
75 }
76
77 @Override
78 public Function<ZonedDateTime, String> getPreFormat() {
79 DateTimeFormatter dateTimeFormatter = getFormatter().orElseGet(this::getFallbackFormatter);
80 return v -> v == null ? "" : dateTimeFormatter.format(v);
81 }
82
83 @Override
84 public Function<String, String> getPostFormat() {
85 return Function.identity();
86 }
87
88 public Function<String, ZonedDateTime> getParser() {
89 return value -> getFormatter().map(f -> {
90 try {
91 return ZonedDateTime.parse(value, f);
92 } catch (DateTimeParseException e) {
93 return null;
94 }
95 }).orElseGet(() -> parseLong(value).map(getLongParser())
96 .orElseGet(() -> ZonedDateTime.parse(value, getFallbackFormatter())));
97 }
98
99 private Optional<Long> parseLong(String value) {
100 try {
101 return Optional.of(Long.parseLong(value));
102 } catch (NumberFormatException e) {
103 return Optional.empty();
104 }
105 }
106
107 public Function<Long, ZonedDateTime> getLongParser() {
108 return longValue -> ZonedDateTime.ofInstant(Instant.ofEpochMilli(longValue), getTimezone());
109 }
110
111 public Optional<DateTimeFormatter> getFormatter() {
112 return Optional.ofNullable(format)
113 .map(DateTimeFormatter::ofPattern)
114 .map(formatter -> formatter.withZone(getTimezone()));
115 }
116
117 public DateTimeFormatter getFallbackFormatter() {
118 return DateTimeFormatter.ISO_DATE_TIME.withZone(getTimezone());
119 }
120
121 @Override
122 public String toString() {
123 return new StringJoiner(", ", DateDefinition.class.getSimpleName() + "[", "]")
124 .add("timezone='" + timezone + "'")
125 .add("value=" + value)
126 .add(super.toString())
127 .toString();
128 }
129 }