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(((LocalDateTime) value).toLocalDate());
050 } else if (value instanceof Date) {
051 super.setValueInternal(ofEpochDay(((Date) value).getTime()));
052 } else if (value instanceof Calendar) {
053 super.setValueInternal(ofEpochDay(((Calendar) value).getTime().getTime()));
054 } else if (value instanceof Number) {
055 super.setValueInternal(ofEpochDay(((Number) value).longValue()));
056 } else if (value instanceof List) {
057 handleAsList((List) value);
058 } else if (value instanceof Map) {
059 handleAsMap((Map) value);
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((Number) val));
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 (Integer) values.get(0),
108 (Integer) values.get(1),
109 (Integer) values.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 == val) val = 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((Number) val);
147 }
148 throw illegalValue(map, LocalDate.class);
149 }
150 }
|