blob: 69ed8865b810fd689d014d89923daecd17b4bc86 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Roman Grigoriadi
******************************************************************************/
package org.eclipse.persistence.json.bind.internal.serializer;
import org.eclipse.persistence.json.bind.internal.JsonbContext;
import org.eclipse.persistence.json.bind.internal.ProcessingContext;
import org.eclipse.persistence.json.bind.internal.Unmarshaller;
import org.eclipse.persistence.json.bind.model.JsonBindingModel;
import javax.json.bind.annotation.JsonbDateFormat;
import java.lang.reflect.Type;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
/**
* @author David Král
*/
public class CalendarTypeDeserializer extends AbstractValueTypeDeserializer<Calendar> {
private final Calendar calendarTemplate;
public CalendarTypeDeserializer(JsonBindingModel model) {
super(Calendar.class, model);
calendarTemplate = Calendar.getInstance();
calendarTemplate.clear();
}
/**
* Parses with ISO_DATE_TIME format and converts to util.Calendar thereafter.
* TODO PERF subject to reconsider if conversion between java.time and java.util outweights threadsafe java.time formatter.
* @param jsonValue value to parse
* @param locale locale
* @return epoch millisecond
*/
private Long parseDefaultDateTime(String jsonValue, Locale locale) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME.withLocale(locale);
final TemporalAccessor temporal = dateTimeFormatter.parse(jsonValue);
//With timezone
if (temporal.isSupported(ChronoField.OFFSET_SECONDS)) {
final ZonedDateTime zdt = ZonedDateTime.from(temporal);
return zdt.toInstant().toEpochMilli();
}
//No timezone
LocalDateTime dateTime = LocalDateTime.from(temporal);
return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
private Date parseDefaultDate(String jsonValue, Locale locale) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_DATE.withLocale(locale);
LocalDate localDate = LocalDate.parse(jsonValue, dateTimeFormatter);
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
@Override
protected Calendar deserialize(String jsonValue, Unmarshaller unmarshaller, Type rtType) {
final JsonbContext jsonbContext = unmarshaller.getJsonbContext();
final JsonbDateFormatter formatter = jsonbContext.getComponentMatcher().getDateFormatter(model);
Calendar result = (Calendar) calendarTemplate.clone();
final String format = formatter.getFormat();
if (JsonbDateFormat.TIME_IN_MILLIS.equals(format)) {
result.setTimeInMillis(Long.parseLong(jsonValue));
return result;
}
Locale locale = jsonbContext.getLocale(formatter.getLocale());
if (JsonbDateFormat.DEFAULT_FORMAT.equals(format)) {
final boolean timed = jsonValue.contains("T");
if (timed) {
result.setTimeInMillis(parseDefaultDateTime(jsonValue, locale));
return result;
} else {
result.setTime(parseDefaultDate(jsonValue, locale));
return result;
}
}
DateTimeFormatter customFormat = DateTimeFormatter.ofPattern(format, locale);
final TemporalAccessor parsed = customFormat.parse(jsonValue);
result.setTime(new Date(Instant.from(parsed).toEpochMilli()));
return result;
}
}