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