LocalDatePropertyEditor.java
001 /*
002  * SPDX-License-Identifier: Apache-2.0
003  *
004  * Copyright 2008-2017 the original author or authors.
005  *
006  * Licensed under the Apache License, Version 2.0 (the "License");
007  * you may not use this file except in compliance with the License.
008  * You may obtain a copy of the License at
009  *
010  *     http://www.apache.org/licenses/LICENSE-2.0
011  *
012  * Unless required by applicable law or agreed to in writing, software
013  * distributed under the License is distributed on an "AS IS" BASIS,
014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015  * See the License for the specific language governing permissions and
016  * limitations under the License.
017  */
018 package griffon.core.editors;
019 
020 import griffon.core.formatters.Formatter;
021 import griffon.core.formatters.LocalDateFormatter;
022 import griffon.metadata.PropertyEditorFor;
023 
024 import java.time.LocalDate;
025 import java.time.LocalDateTime;
026 import java.time.format.DateTimeParseException;
027 import java.util.ArrayList;
028 import java.util.Calendar;
029 import java.util.Date;
030 import java.util.List;
031 import java.util.Map;
032 
033 import static griffon.util.GriffonNameUtils.isBlank;
034 import static java.time.LocalDate.ofEpochDay;
035 
036 /**
037  @author Andres Almiray
038  @since 2.4.0
039  */
040 @PropertyEditorFor(LocalDate.class)
041 public class LocalDatePropertyEditor extends AbstractPropertyEditor {
042     @Override
043     protected void setValueInternal(Object value) {
044         if (null == value) {
045             super.setValueInternal(null);
046         else if (value instanceof CharSequence) {
047             handleAsString(String.valueOf(value));
048         else if (value instanceof LocalDate) {
049             super.setValueInternal(value);
050         else if (value instanceof LocalDateTime) {
051             super.setValueInternal(((LocalDateTimevalue).toLocalDate());
052         else if (value instanceof Date) {
053             super.setValueInternal(ofEpochDay(((Datevalue).getTime()));
054         else if (value instanceof Calendar) {
055             super.setValueInternal(ofEpochDay(((Calendarvalue).getTime().getTime()));
056         else if (value instanceof Number) {
057             super.setValueInternal(ofEpochDay(((Numbervalue).longValue()));
058         else if (value instanceof List) {
059             handleAsList((Listvalue);
060         else if (value instanceof Map) {
061             handleAsMap((Mapvalue);
062         else {
063             throw illegalValue(value, LocalDate.class);
064         }
065     }
066 
067     protected void handleAsString(String str) {
068         if (isBlank(str)) {
069             super.setValueInternal(null);
070             return;
071         }
072 
073         try {
074             super.setValueInternal(LocalDate.parse(str));
075         catch (DateTimeParseException dtpe) {
076             throw illegalValue(str, LocalDate.class, dtpe);
077         }
078     }
079 
080     @Override
081     protected Formatter<LocalDate> resolveFormatter() {
082         return isBlank(getFormat()) null new LocalDateFormatter(getFormat());
083     }
084 
085     protected void handleAsList(List<?> list) {
086         if (list.isEmpty()) {
087             super.setValueInternal(null);
088             return;
089         }
090 
091         List<Object> values = new ArrayList<>();
092         values.addAll(list);
093         if (values.size() != 3) {
094             throw illegalValue(list, LocalDate.class);
095         }
096 
097         for (int i = 0, valuesSize = values.size(); i < valuesSize; i++) {
098             Object val = values.get(i);
099             if (val instanceof Number) {
100                 values.set(i, parse((Numberval));
101             else if (val instanceof CharSequence) {
102                 values.set(i, parse(String.valueOf(val)));
103             else {
104                 throw illegalValue(list, LocalDate.class);
105             }
106         }
107         super.setValueInternal(
108             LocalDate.of(
109                 (Integervalues.get(0),
110                 (Integervalues.get(1),
111                 (Integervalues.get(2)
112             )
113         );
114     }
115 
116     protected void handleAsMap(Map<?, ?> map) {
117         if (map.isEmpty()) {
118             super.setValueInternal(null);
119             return;
120         }
121 
122         int y = getMapValue(map, "year"1970);
123         int m = getMapValue(map, "month"1);
124         int d = getMapValue(map, "day"1);
125         super.setValueInternal(LocalDate.of(y, m, d));
126     }
127 
128     protected int parse(String val) {
129         try {
130             return Integer.parseInt(val.trim());
131         catch (NumberFormatException e) {
132             throw illegalValue(val, LocalDate.class, e);
133         }
134     }
135 
136     protected int parse(Number val) {
137         return val.intValue();
138     }
139 
140     protected int getMapValue(Map<?, ?> map, String key, int defaultValue) {
141         Object val = map.get(key);
142         if (null == valval = map.get(String.valueOf(key.charAt(0)));
143         if (null == val) {
144             return defaultValue;
145         else if (val instanceof CharSequence) {
146             return parse(String.valueOf(val));
147         else if (val instanceof Number) {
148             return parse((Numberval);
149         }
150         throw illegalValue(map, LocalDate.class);
151     }
152 }