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