LocalDateTimePropertyEditor.java
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((LocalDatevalue, LocalTime.of(0000)));
051         else if (value instanceof Date) {
052             handleAsDate((Datevalue);
053         else if (value instanceof Calendar) {
054             handleAsCalendar((Calendarvalue);
055         else if (value instanceof Number) {
056             handleAsDate(new Date(((Numbervalue).longValue()));
057         else if (value instanceof List) {
058             handleAsList((Listvalue);
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.MILLISECOND1000;
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((Numberval));
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                 (Integervalues.get(0),
143                 (Integervalues.get(1),
144                 (Integervalues.get(2),
145                 (Integervalues.get(3),
146                 (Integervalues.get(4),
147                 (Integervalues.get(5),
148                 (Integervalues.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 }