001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.util.convert.converter;
018
019import java.time.format.DateTimeFormatter;
020import java.time.format.DateTimeParseException;
021import java.time.temporal.Temporal;
022import java.time.temporal.TemporalAccessor;
023import java.util.Locale;
024
025import org.apache.wicket.util.string.Strings;
026
027/**
028 * A base class for all java.time.** related converters
029 *
030 * @param <T>
031 *     the type of the Temporal that is supported by this converter
032 */
033public abstract class AbstractJavaTimeConverter<T extends Temporal> extends AbstractConverter<T>
034{
035        private static final long serialVersionUID = 1L;
036
037        /**
038         * Creates a new instance of D out of the passed date(time) as long
039         * @param temporalAccessor
040         *      the date(time) in millis since Epoch
041         * @return a new instance of the specific type D
042         */
043        protected abstract T createTemporal(TemporalAccessor temporalAccessor);
044
045        @Override
046        public T convertToObject(final String value, Locale locale)
047        {
048                if (Strings.isEmpty(value))
049                {
050                        return null;
051                }
052
053                DateTimeFormatter dateTimeFormatter = getDateTimeFormatter(locale);
054                
055                TemporalAccessor temporalAccessor;
056                try {
057                        temporalAccessor = dateTimeFormatter.parse(value);
058                } catch (DateTimeParseException ex) {
059                        throw newConversionException("Cannot parse '" + value, value, locale);
060                }
061                
062                return createTemporal(temporalAccessor);
063        }
064
065        @Override
066        public String convertToString(final T value, final Locale locale)
067        {
068                if (value == null)
069                {
070                        return null;
071                }
072
073                final DateTimeFormatter dateTimeFormatter = getDateTimeFormatter(locale);
074                if (dateTimeFormatter != null)
075                {
076                        return dateTimeFormatter.format(value);
077                }
078                return value.toString();
079        }
080
081        /**
082         * @param locale
083         * @return Returns the date time format.
084         */
085        public DateTimeFormatter getDateTimeFormatter(Locale locale)
086        {
087                if (locale == null)
088                {
089                        locale = Locale.getDefault();
090                }
091
092                return getDateTimeFormatter().withLocale(locale);
093        }
094
095        protected abstract DateTimeFormatter getDateTimeFormatter();
096}