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