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.LocalDateTimeFormatter;
022 import griffon.metadata.PropertyEditorFor;
023
024 import java.time.LocalDate;
025 import java.time.LocalDateTime;
026 import java.time.LocalTime;
027 import java.time.format.DateTimeParseException;
028 import java.util.ArrayList;
029 import java.util.Calendar;
030 import java.util.Date;
031 import java.util.List;
032
033 import static griffon.util.GriffonNameUtils.isBlank;
034
035 /**
036 * @author Andres Almiray
037 * @since 2.4.0
038 */
039 @PropertyEditorFor(LocalDateTime.class)
040 public class LocalDateTimePropertyEditor extends AbstractPropertyEditor {
041 @Override
042 protected void setValueInternal(Object value) {
043 if (null == value) {
044 super.setValueInternal(null);
045 } else if (value instanceof CharSequence) {
046 handleAsString(String.valueOf(value));
047 } else if (value instanceof LocalDateTime) {
048 super.setValueInternal(value);
049 } else if (value instanceof LocalDate) {
050 super.setValueInternal(LocalDateTime.of((LocalDate) value, LocalTime.of(0, 0, 0, 0)));
051 } else if (value instanceof Date) {
052 handleAsDate((Date) value);
053 } else if (value instanceof Calendar) {
054 handleAsCalendar((Calendar) value);
055 } else if (value instanceof Number) {
056 handleAsDate(new Date(((Number) value).longValue()));
057 } else if (value instanceof List) {
058 handleAsList((List) value);
059 } else {
060 throw illegalValue(value, LocalDateTime.class);
061 }
062 }
063
064 protected void handleAsDate(Date date) {
065 Calendar c = Calendar.getInstance();
066 c.setTime(date);
067 handleAsCalendar(c);
068 }
069
070 protected void handleAsCalendar(Calendar value) {
071 int h = value.get(Calendar.HOUR);
072 int i = value.get(Calendar.MINUTE);
073 int s = value.get(Calendar.SECOND);
074 int n = value.get(Calendar.MILLISECOND) * 1000;
075 super.setValueInternal(LocalDateTime.of(LocalDate.ofEpochDay(value.getTime().getTime()), LocalTime.of(h, i, s, n)));
076 }
077
078 protected void handleAsString(String str) {
079 if (isBlank(str)) {
080 super.setValueInternal(null);
081 return;
082 }
083
084 try {
085 super.setValueInternal(LocalDateTime.parse(str));
086 } catch (DateTimeParseException dtpe) {
087 throw illegalValue(str, LocalDateTime.class, dtpe);
088 }
089 }
090
091 @Override
092 protected Formatter<LocalDateTime> resolveFormatter() {
093 return isBlank(getFormat()) ? null : new LocalDateTimeFormatter(getFormat());
094 }
095
096 protected void handleAsList(List<?> list) {
097 if (list.isEmpty()) {
098 super.setValueInternal(null);
099 return;
100 }
101
102 List<Object> values = new ArrayList<>();
103 values.addAll(list);
104 switch (list.size()) {
105 case 7:
106 // ok
107 break;
108 case 6:
109 values.add(0d);
110 break;
111 case 5:
112 values.add(0d);
113 values.add(0d);
114 break;
115 case 4:
116 values.add(0d);
117 values.add(0d);
118 values.add(0d);
119 break;
120 case 3:
121 values.add(0d);
122 values.add(0d);
123 values.add(0d);
124 values.add(0d);
125 break;
126 default:
127 throw illegalValue(list, LocalDateTime.class);
128 }
129
130 for (int i = 0, valuesSize = values.size(); i < valuesSize; i++) {
131 Object val = values.get(i);
132 if (val instanceof Number) {
133 values.set(i, parse((Number) val));
134 } else if (val instanceof CharSequence) {
135 values.set(i, parse(String.valueOf(val)));
136 } else {
137 throw illegalValue(list, LocalDateTime.class);
138 }
139 }
140 super.setValueInternal(
141 LocalDateTime.of(
142 (Integer) values.get(0),
143 (Integer) values.get(1),
144 (Integer) values.get(2),
145 (Integer) values.get(3),
146 (Integer) values.get(4),
147 (Integer) values.get(5),
148 (Integer) values.get(6)
149 )
150 );
151 }
152
153 protected int parse(String val) {
154 try {
155 return Integer.parseInt(val.trim());
156 } catch (NumberFormatException e) {
157 throw illegalValue(val, LocalDateTime.class, e);
158 }
159 }
160
161 protected int parse(Number val) {
162 return val.intValue();
163 }
164 }
|