View Javadoc
1   /*
2    * Licensed under the Apache License, Version 2.0 (the "License");
3    * you may not use this file except in compliance with the License.
4    * You may obtain a copy of the License at
5    *
6    * http://www.apache.org/licenses/LICENSE-2.0
7    *
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS,
10   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11   * See the License for the specific language governing permissions and
12   * limitations under the License.
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       * Timezone for this date. Field injected by Maven.
40       */
41      String timezone = null;
42  
43      /**
44       * Value for this date. Field injected by Maven.
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 }