001package org.apache.turbine.services.localization;
002
003
004import org.apache.commons.lang3.StringUtils;
005import org.apache.logging.log4j.LogManager;
006import org.apache.logging.log4j.Logger;
007import org.apache.turbine.Turbine;
008import org.apache.turbine.services.TurbineBaseService;
009
010import java.time.ZoneId;
011import java.time.format.DateTimeFormatter;
012import java.time.format.DateTimeParseException;
013import java.time.temporal.TemporalAccessor;
014import java.util.Locale;
015
016/**
017 * This service is used to format {@link TemporalAccessor} and
018 * {@link #map(String, DateTimeFormatter, Locale)} (different falvors)
019 * objects into strings.
020 *
021 * The methods may throw {@link java.time.temporal.UnsupportedTemporalTypeException} or
022 * {@link DateTimeParseException}.
023 * if the source and the target format do not match appropriately.
024 *
025 */
026public class DateTimeFormatterService
027        extends TurbineBaseService implements DateTimeFormatterInterface {
028
029    public static String SERVICE_NAME = "DateTimeFormatterService";
030
031    public static String ROLE = DateTimeFormatterService.class.getName();
032
033    /** Default date format. find supporrted formats in {@link DateTimeFormatterService} */
034    private static final String DATE_TIME_FORMAT_DEFAULT = "MM/dd/yyyy";
035
036    /**
037     * Property tag for the date format that is to be used for the web
038     * application.
039     */
040    private static final String DATE_TIME_FORMAT_KEY = "tool.datetimeTool.format";
041
042    private String dateTimeFormatPattern = null;
043    
044    private DateTimeFormatter defaultFormat = null;
045
046    @Override
047    public DateTimeFormatter getDefaultFormat()
048    {
049        return defaultFormat;
050    }
051
052    @Override
053    public String getDateTimeFormatPattern() {
054        return dateTimeFormatPattern;
055    }
056
057    private static final Logger log = LogManager.getLogger(DateTimeFormatterService.class);
058
059    /**
060     * Initialize the service.
061     *
062     * the {@link #defaultFormat} from {@link #dateTimeFormatPattern} is initialized with
063     * the default Locale {@link Locale#getDefault()} and default zone: {@link ZoneId#systemDefault()}.
064     *
065     */
066    @Override
067    public void init()
068    {
069        dateTimeFormatPattern = Turbine.getConfiguration()
070                .getString(DATE_TIME_FORMAT_KEY, DATE_TIME_FORMAT_DEFAULT);
071        defaultFormat = DateTimeFormatter.ofPattern(dateTimeFormatPattern)
072                .withLocale(Locale.getDefault()).withZone(ZoneId.systemDefault());
073
074        log.info("Initialized DateTimeFormatterService with pattern {}, locale {} and zone {}",
075                dateTimeFormatPattern, defaultFormat.getLocale(), defaultFormat.getZone());
076        setInit(true);
077    }
078
079    @Override
080    public <T extends TemporalAccessor> String format(T temporalAccessor)
081    {
082        return defaultFormat.format(temporalAccessor);
083    }
084
085    @Override
086    public <T extends TemporalAccessor> String format(T temporalAccessor, String dateFormatString)
087    {
088        return format(temporalAccessor, dateFormatString, null);
089    }
090
091    @Override
092    public <T extends TemporalAccessor> String format(T temporalAccessor, String dateFormatString, Locale locale)
093    {
094        String result = null;
095
096        if (StringUtils.isEmpty(dateFormatString) || temporalAccessor == null)
097        {
098            result = "";
099        }
100        else
101        {
102            DateTimeFormatter dtf = DateTimeFormatter.ofPattern(dateFormatString);
103            if (locale != null)
104            {
105                dtf.withLocale(locale);
106            }
107            result = dtf.format(temporalAccessor);
108        }
109        return result;
110    }
111    
112    @Override
113    public String map(String src, String outgoingFormatPattern, Locale locale, String incomingFormatPattern)
114    {
115        if (StringUtils.isEmpty(src) || outgoingFormatPattern == null)
116        {
117            return "";
118        }
119        if (incomingFormatPattern == null)
120        {
121            incomingFormatPattern = dateTimeFormatPattern;
122        }
123        if (incomingFormatPattern.equals( outgoingFormatPattern )) {
124            return "";
125        }
126        DateTimeFormatter incomingFormat = DateTimeFormatter.ofPattern(incomingFormatPattern);
127        DateTimeFormatter outgoingFormat = DateTimeFormatter.ofPattern(outgoingFormatPattern);
128        if (locale != null)
129        {
130            outgoingFormat = outgoingFormat.withLocale( locale );
131            //incomingFormat = incomingFormat.withLocale( locale );
132        }
133        return map( src, outgoingFormat, locale, incomingFormat );
134    }
135
136    @Override
137    public String map(String src, DateTimeFormatter outgoingFormat, Locale locale,
138                      DateTimeFormatter incomingFormat)
139    {
140        if (StringUtils.isEmpty(src) || outgoingFormat == null)
141        {
142            return "";
143        }
144        if (incomingFormat == null)
145        {
146            incomingFormat = defaultFormat;
147        }
148        if (incomingFormat.equals( outgoingFormat )) {
149            return "";
150        }
151        if (locale != null)
152        {
153            outgoingFormat = outgoingFormat.withLocale( locale );
154            //incomingFormat = incomingFormat.withLocale( locale );
155        }
156        return  outgoingFormat.format(
157                incomingFormat.parse( src ));
158    }
159
160    @Override
161    public String mapTo(String src, DateTimeFormatter outgoingFormat)
162    {
163        return map( src, outgoingFormat, null, defaultFormat );
164    }
165
166    @Override
167    public String mapFrom(String src, DateTimeFormatter incomingFormat)
168    {
169        return map( src, defaultFormat, null, incomingFormat );
170    }
171
172    @Override
173    public String map(String src, DateTimeFormatter outgoingFormat, Locale locale)
174    {
175        return map( src, outgoingFormat, locale, defaultFormat );
176    }
177}