net.sf.jasperreports.engine.fill.MessageFormatWrapper Maven / Gradle / Ivy
The newest version!
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2023 Cloud Software Group, Inc. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JasperReports is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JasperReports. If not, see .
*/
package net.sf.jasperreports.engine.fill;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.Format;
import java.text.MessageFormat;
import java.text.ParsePosition;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.Locale;
/**
* {@link MessageFormat} does not work with classes of the java.time package such as {@link LocalDate} This is by design and won't be fixed:
* https://bugs.openjdk.org/browse/JDK-8016743
*
* This class wraps a {@link MessageFormat} and converts classes of the java.time package into {@link Date} objects
*
* @author Guillaume Toison
*/
public class MessageFormatWrapper
{
/**
* @param pattern The message pattern, for instance "since {0, date, dd-MM-yy}"
* @param locale The locale, must be non-null
* @param arguments the message parameters
* @return the constructed message
*
* @see MessageFormat#format(java.lang.Object[],java.lang.StringBuffer, java.text.FieldPosition)
*/
public static String format(String pattern, Locale locale, Object... arguments)
{
MessageFormat messageFormat = new MessageFormat("");
messageFormat.setLocale(locale);
messageFormat.applyPattern(pattern);
Format[] formats = messageFormat.getFormats();
for (int i = 0; i < formats.length; i++)
{
Format format = formats[i];
if (format instanceof DateFormat)
{
messageFormat.setFormat(i, new DateFormatWrapper(format));
}
}
return messageFormat.format(arguments);
}
private static class DateFormatWrapper extends Format
{
private static final long serialVersionUID = 1L;
private final Format format;
private DateFormatWrapper(Format format)
{
this.format = format;
}
@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos)
{
if (obj instanceof TemporalAccessor)
{
TemporalAccessor ta = (TemporalAccessor) obj;
final Instant instant;
if (obj instanceof LocalDate)
{
LocalDate date = (LocalDate) obj;
instant = date.atStartOfDay(ZoneId.systemDefault()).toInstant();
}
else if (obj instanceof LocalDateTime)
{
LocalDateTime dateTime = (LocalDateTime) obj;
instant = dateTime.atZone(ZoneId.systemDefault()).toInstant();
}
else if (obj instanceof ZonedDateTime)
{
ZonedDateTime dateTime = (ZonedDateTime) obj;
instant = dateTime.toInstant();
}
else
{
instant = Instant.from(ta);
}
obj = Date.from(instant);
}
return format.format(obj, toAppendTo, pos);
}
@Override
public Object parseObject(String source, ParsePosition pos)
{
return format.parseObject(source, pos);
}
}
}