LocalDatePropertyEditor.java
001 /*
002  * Copyright 2008-2016 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     protected void setValueInternal(Object value) {
041         if (null == value) {
042             super.setValueInternal(null);
043         else if (value instanceof CharSequence) {
044             handleAsString(String.valueOf(value));
045         else if (value instanceof LocalDate) {
046             super.setValueInternal(value);
047         else if (value instanceof LocalDateTime) {
048             super.setValueInternal(((LocalDateTimevalue).toLocalDate());
049         else if (value instanceof Date) {
050             super.setValueInternal(ofEpochDay(((Datevalue).getTime()));
051         else if (value instanceof Calendar) {
052             super.setValueInternal(ofEpochDay(((Calendarvalue).getTime().getTime()));
053         else if (value instanceof Number) {
054             super.setValueInternal(ofEpochDay(((Numbervalue).longValue()));
055         else if (value instanceof List) {
056             handleAsList((Listvalue);
057         else if (value instanceof Map) {
058             handleAsMap((Mapvalue);
059         else {
060             throw illegalValue(value, LocalDate.class);
061         }
062     }
063 
064     protected void handleAsString(String str) {
065         if (isBlank(str)) {
066             super.setValueInternal(null);
067             return;
068         }
069 
070         try {
071             super.setValueInternal(LocalDate.parse(str));
072         catch (DateTimeParseException dtpe) {
073             throw illegalValue(str, LocalDate.class, dtpe);
074         }
075     }
076 
077     protected Formatter<LocalDate> resolveFormatter() {
078         return isBlank(getFormat()) null new LocalDateFormatter(getFormat());
079     }
080 
081     protected void handleAsList(List<?> list) {
082         if (list.isEmpty()) {
083             super.setValueInternal(null);
084             return;
085         }
086 
087         List<Object> values = new ArrayList<>();
088         values.addAll(list);
089         if (values.size() != 3) {
090             throw illegalValue(list, LocalDate.class);
091         }
092 
093         for (int i = 0, valuesSize = values.size(); i < valuesSize; i++) {
094             Object val = values.get(i);
095             if (val instanceof Number) {
096                 values.set(i, parse((Numberval));
097             else if (val instanceof CharSequence) {
098                 values.set(i, parse(String.valueOf(val)));
099             else {
100                 throw illegalValue(list, LocalDate.class);
101             }
102         }
103         super.setValueInternal(
104             LocalDate.of(
105                 (Integervalues.get(0),
106                 (Integervalues.get(1),
107                 (Integervalues.get(2)
108             )
109         );
110     }
111 
112     protected void handleAsMap(Map<?, ?> map) {
113         if (map.isEmpty()) {
114             super.setValueInternal(null);
115             return;
116         }
117 
118         int y = getMapValue(map, "year"1970);
119         int m = getMapValue(map, "month"1);
120         int d = getMapValue(map, "day"1);
121         super.setValueInternal(LocalDate.of(y, m, d));
122     }
123 
124     protected int parse(String val) {
125         try {
126             return Integer.parseInt(val.trim());
127         catch (NumberFormatException e) {
128             throw illegalValue(val, LocalDate.class, e);
129         }
130     }
131 
132     protected int parse(Number val) {
133         return val.intValue();
134     }
135 
136     protected int getMapValue(Map<?, ?> map, String key, int defaultValue) {
137         Object val = map.get(key);
138         if (null == valval = map.get(String.valueOf(key.charAt(0)));
139         if (null == val) {
140             return defaultValue;
141         else if (val instanceof CharSequence) {
142             return parse(String.valueOf(val));
143         else if (val instanceof Number) {
144             return parse((Numberval);
145         }
146         throw illegalValue(map, LocalDate.class);
147     }
148 }