/** * Converts to JSON string. * * @param object Object to convert. * @param formatter Formatter to use. * @param jsonbContext JSON-B context. * @return JSON representation of given object. */ public String toJson(T object, JsonbDateFormatter formatter, JsonbContext jsonbContext) { if (JsonbDateFormat.TIME_IN_MILLIS.equals(formatter.getFormat())) { return String.valueOf(toInstant(object).toEpochMilli()); } else if (formatter.getDateTimeFormatter() != null) { return formatWithFormatter(object, formatter.getDateTimeFormatter()); } else { DateTimeFormatter configDateTimeFormatter = jsonbContext.getConfigProperties().getConfigDateFormatter().getDateTimeFormatter(); if (configDateTimeFormatter != null) { return formatWithFormatter(object, configDateTimeFormatter); } } if (jsonbContext.getConfigProperties().isStrictIJson()) { return formatStrictIJson(object); } return formatDefault(object, jsonbContext.getConfigProperties().getLocale(formatter.getLocale())); }
@Override public T deserialize(String jsonValue, Unmarshaller unmarshaller, Type rtType) { final JsonbDateFormatter formatter = getJsonbDateFormatter(unmarshaller.getJsonbContext()); if (JsonbDateFormat.TIME_IN_MILLIS.equals(formatter.getFormat())) { return fromInstant(Instant.ofEpochMilli(Long.parseLong(jsonValue))); } else if (formatter.getDateTimeFormatter() != null) { return parseWithFormatterInternal(jsonValue, formatter.getDateTimeFormatter()); } else { DateTimeFormatter configDateTimeFormatter = unmarshaller.getJsonbContext().getConfigProperties().getConfigDateFormatter().getDateTimeFormatter(); if (configDateTimeFormatter != null) { return parseWithFormatterInternal(jsonValue, configDateTimeFormatter); } } final boolean strictIJson = unmarshaller.getJsonbContext().getConfigProperties().isStrictIJson(); if (strictIJson) { return parseWithFormatterInternal(jsonValue, JsonbDateFormatter.IJSON_DATE_FORMATTER); } try { return parseDefault(jsonValue, unmarshaller.getJsonbContext().getConfigProperties().getLocale(formatter.getLocale())); } catch (DateTimeParseException e) { throw new JsonbException(Messages.getMessage(MessageKeys.DATE_PARSE_ERROR, jsonValue), e); } }
/** * Creates {@link JsonbDateFormatter} caches formatter instance if possible. * For DEFAULT_FORMAT appropriate singleton instances from java.time.format.DateTimeFormatter * are used in date converters. */ private JsonbDateFormatter createJsonbDateFormatter(String format, String locale, Property property) { if (JsonbDateFormat.TIME_IN_MILLIS.equals(format) || JsonbDateFormat.DEFAULT_FORMAT.equals(format)) { //for epochMillis formatter is not used, for default format singleton instances of DateTimeFormatter //are used in the converters return new JsonbDateFormatter(format, locale); } final Optional<Class<?>> optionalRawType = ReflectionUtils.getOptionalRawType(property.getPropertyType()); final Class<?> propertyRawType = optionalRawType.orElse(null); if (propertyRawType != null && !TemporalAccessor.class.isAssignableFrom(propertyRawType) && !Date.class.isAssignableFrom(propertyRawType) && !Calendar.class.isAssignableFrom(propertyRawType)) { throw new IllegalStateException(Messages.getMessage(MessageKeys.UNSUPPORTED_DATE_TYPE, propertyRawType)); } DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format, Locale.forLanguageTag(locale)); return new JsonbDateFormatter(dateTimeFormatter, format, locale); }
@Test public void testDifferentConfigsLocalDateTime() { final LocalDateTime dateTime = LocalDateTime.of(2015, 2, 16, 13, 21); final long millis = dateTime.atZone(ZoneId.of("Z")).toInstant().toEpochMilli(); final ScalarValueWrapper<LocalDateTime> pojo = new ScalarValueWrapper<>(); pojo.setValue(dateTime); final String expected = "{\"value\":\"2015-02-16T13:21:00\"}"; assertEquals(expected, jsonb.toJson(pojo)); final Jsonb jsonbCustom = JsonbBuilder.create(new JsonbConfig().withDateFormat(JsonbDateFormat.TIME_IN_MILLIS, Locale.FRENCH)); assertEquals("{\"value\":\"" + millis + "\"}", jsonbCustom.toJson(pojo)); ScalarValueWrapper<LocalDateTime> result = this.jsonb.fromJson(expected, new TestTypeToken<ScalarValueWrapper<LocalDateTime>>(){}.getType()); assertEquals(dateTime, result.getValue()); result = jsonbCustom.fromJson("{\"value\":\"" + millis + "\"}", new TestTypeToken<ScalarValueWrapper<LocalDateTime>>(){}.getType()); assertEquals(dateTime, result.getValue()); }
/** * Search {@link JsonbDateFormat} on property, if not found looks at annotations declared on property type class. * * @param property Property to search on. * @return Map of {@link JsonbDateFormatter} instances categorized by their scopes (class, property, getter or setter). If there is no date * formatter specified for given property, an empty map would be returned */ public Map<AnnotationTarget, JsonbDateFormatter> getJsonbDateFormatCategorized(Property property) { Objects.requireNonNull(property); Map<AnnotationTarget, JsonbDateFormatter> result = new HashMap<>(); Map<AnnotationTarget, JsonbDateFormat> annotationFromPropertyCategorized = getAnnotationFromPropertyCategorized(JsonbDateFormat.class, property); if (annotationFromPropertyCategorized.size() != 0) { annotationFromPropertyCategorized.forEach((key, annotation) -> result.put(key, createJsonbDateFormatter(annotation.value(), annotation.locale(), property))); } // No date format on property, try class level // if property is not TypeVariable and its class is not date skip it final Optional<Class<?>> propertyRawTypeOptional = ReflectionUtils.getOptionalRawType(property.getPropertyType()); if (propertyRawTypeOptional.isPresent()) { Class<?> rawType = propertyRawTypeOptional.get(); if (!(Date.class.isAssignableFrom(rawType) || Calendar.class.isAssignableFrom(rawType) || TemporalAccessor.class.isAssignableFrom(rawType))) { return new HashMap<>(); } } JsonbDateFormat classLevelDateFormatter = findAnnotation(property.getDeclaringClassElement().getAnnotations(), JsonbDateFormat.class); if(classLevelDateFormatter != null) { result.put(AnnotationTarget.CLASS, createJsonbDateFormatter(classLevelDateFormatter.value(), classLevelDateFormatter.locale(), property)); } return result; }
/** * Search for {@link JsonbDateFormat} annotation on java class and construct {@link JsonbDateFormatter}. * If not found looks at annotations declared on property type class. * @param clazzElement class to search not null * @return formatter to use */ public JsonbDateFormatter getJsonbDateFormat(JsonbAnnotatedElement<Class<?>> clazzElement) { Objects.requireNonNull(clazzElement); final JsonbDateFormat format = findAnnotation(clazzElement.getAnnotations(), JsonbDateFormat.class); if (format == null) { return jsonbContext.getConfigProperties().getConfigDateFormatter(); } return new JsonbDateFormatter(format.value(), format.locale()); }
public JsonbDateFormatter getConstructorDateFormatter(JsonbAnnotatedElement<Parameter> param) { JsonbDateFormat annotation = param.getAnnotation(JsonbDateFormat.class); if (annotation != null) { return new JsonbDateFormatter(DateTimeFormatter .ofPattern(annotation.value(), Locale.forLanguageTag(annotation.locale())), annotation.value(), annotation.locale()); } return null; }
private JsonbDateFormatter initDateFormatter(Locale locale) { final String dateFormat = getGlobalConfigJsonbDateFormat(); if (JsonbDateFormat.DEFAULT_FORMAT.equals(dateFormat) || JsonbDateFormat.TIME_IN_MILLIS.equals(dateFormat)) { return new JsonbDateFormatter(dateFormat, locale.toLanguageTag()); } return new JsonbDateFormatter(DateTimeFormatter.ofPattern(dateFormat, locale), dateFormat, locale.toLanguageTag()); }
private String getGlobalConfigJsonbDateFormat() { final Optional<Object> formatProperty = jsonbConfig.getProperty(JsonbConfig.DATE_FORMAT); return formatProperty.map(f -> { if (!(f instanceof String)) { throw new JsonbException(Messages.getMessage(MessageKeys.JSONB_CONFIG_PROPERTY_INVALID_TYPE, JsonbConfig.DATE_FORMAT, String.class.getSimpleName())); } return (String) f; }).orElse(JsonbDateFormat.DEFAULT_FORMAT); }
/** * Converts string locale to {@link Locale}. * * @param locale Locale to convert. * @return {@link Locale} instance. */ public Locale getLocale(String locale) { if (locale.equals(JsonbDateFormat.DEFAULT_LOCALE)) { return this.locale; } return Locale.forLanguageTag(locale); }
protected JsonbDateConverterBase(final JsonbDateFormat dateFormat) { final String value = dateFormat.value(); final String locale = dateFormat.locale(); final boolean ms = value.equals(JsonbDateFormat.TIME_IN_MILLIS); formatter = ms ? null : (!locale.equals(JsonbDateFormat.DEFAULT_LOCALE) ? DateTimeFormatter.ofPattern(value).withLocale(newLocale(locale)) : DateTimeFormatter.ofPattern(value)); }
private void validateAnnotations(final Object parameter, final JsonbTypeAdapter adapter, final JsonbDateFormat dateFormat, final JsonbNumberFormat numberFormat, final JohnzonConverter johnzonConverter) { int notNull = adapter != null ? 1 : 0; notNull += dateFormat != null ? 1 : 0; notNull += numberFormat != null ? 1 : 0; notNull += johnzonConverter != null ? 1 : 0; if (notNull > 1) { throw new IllegalArgumentException("Conflicting @JsonbXXX/@JohnzonConverter on " + parameter); } }
private Adapter<?, ?> toConverter(final Type type, final JsonbTypeAdapter adapter, final JsonbDateFormat dateFormat, final JsonbNumberFormat numberFormat) throws InstantiationException, IllegalAccessException { final Adapter converter; if (adapter != null) { final Class<? extends JsonbAdapter> value = adapter.value(); final ParameterizedType pt = findPt(value, JsonbAdapter.class); if (pt == null) { throw new IllegalArgumentException(value + " doesn't implement JsonbAdapter"); } final JohnzonAdapterFactory.Instance<? extends JsonbAdapter> instance = newInstance(value); toRelease.add(instance); final Type[] actualTypeArguments = pt.getActualTypeArguments(); converter = new JohnzonJsonbAdapter(instance.getValue(), actualTypeArguments[0], actualTypeArguments[1]); } else if (dateFormat != null) { // TODO: support lists, LocalDate? if (Date.class == type) { converter = new ConverterAdapter<>(new JsonbDateConverter(dateFormat)); } else if (LocalDateTime.class == type) { converter = new ConverterAdapter<>(new JsonbLocalDateTimeConverter(dateFormat)); } else if (LocalDate.class == type) { converter = new ConverterAdapter<>(new JsonbLocalDateConverter(dateFormat)); } else if (ZonedDateTime.class == type) { converter = new ConverterAdapter<>(new JsonbZonedDateTimeConverter(dateFormat)); } else { throw new IllegalArgumentException(type + " not a supported date type"); } } else if (numberFormat != null) { // TODO: support lists? converter = new ConverterAdapter<>(new JsonbNumberConverter(numberFormat)); } else { converter = new ConverterAdapter<>(new JsonbValueConverter()); } return converter; }
@JsonbDateFormat(value = "MM/dd/yyyy", locale = "Locale.ENGLISH") public void setPublished(LocalDate published) { this.published = published; }
public boolean isDefault() { return JsonbDateFormat.DEFAULT_FORMAT.equals(format); }
@JsonbDateFormat(value = "HH:mm:ss ^^ dd-MM-yyyy", locale = "Europe/Copenhagen") public Date getGetterFormattedDateField() { return getterFormattedDateField; }
@JsonbDateFormat(value = "HH:mm:ss ^^ dd-MM-yyyy", locale = "Europe/Copenhagen") public void setSetterFormattedDateField(Date setterFormattedDateField) { this.setterFormattedDateField = setterFormattedDateField; }
@JsonbDateFormat(value = "HH:mm:ss <> dd-MM-yyyy", locale = "Europe/Copenhagen") public Date getGetterAndFieldFormattedDateField() { return getterAndFieldFormattedDateField; }
@JsonbDateFormat(value = "HH:mm:ss <> dd-MM-yyyy", locale = "Europe/Copenhagen") public void setSetterAndFieldFormattedDateField(Date setterAndFieldFormattedDateField) { this.setterAndFieldFormattedDateField = setterAndFieldFormattedDateField; }
@JsonbDateFormat(value = "HH:mm:ss ^^ dd-MM-yyyy", locale = "Europe/Copenhagen") public Date getGetterAndSetterFormattedDateField() { return getterAndSetterFormattedDateField; }
@JsonbDateFormat(value = "HH:mm:ss <> dd-MM-yyyy", locale = "Europe/Copenhagen") public void setGetterAndSetterFormattedDateField(Date getterAndSetterFormattedDateField) { this.getterAndSetterFormattedDateField = getterAndSetterFormattedDateField; }
@JsonbDateFormat(value = "HH:mm:ss <> dd-MM-yyyy", locale = "Europe/Copenhagen") public Date getGetterAndSetterAndFieldFormattedDateField() { return getterAndSetterAndFieldFormattedDateField; }
@JsonbDateFormat(value = "HH:mm:ss $$ dd-MM-yyyy", locale = "Europe/Copenhagen") public void setGetterAndSetterAndFieldFormattedDateField(Date getterAndSetterAndFieldFormattedDateField) { this.getterAndSetterAndFieldFormattedDateField = getterAndSetterAndFieldFormattedDateField; }
@JsonbCreator public DateConstructor(@JsonbProperty("localDate") @JsonbDateFormat(value = "dd-MM-yyyy", locale = "nl-NL") LocalDate localDate) { this.localDate = localDate; }
public JsonbLocalDateTimeConverter(final JsonbDateFormat dateFormat) { super(dateFormat); }
public JsonbZonedDateTimeConverter(final JsonbDateFormat dateFormat) { super(dateFormat); }
public JsonbDateConverter(final JsonbDateFormat dateFormat) { super(dateFormat); }
public JsonbLocalDateConverter(final JsonbDateFormat dateFormat) { super(dateFormat); }