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