001/*
002 * Copyright 2002-2016 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.format.datetime.standard;
018
019import java.time.format.DateTimeFormatter;
020import java.util.Locale;
021
022import org.springframework.core.NamedThreadLocal;
023import org.springframework.lang.UsesJava8;
024
025/**
026 * A holder for a thread-local user {@link DateTimeContext}.
027 *
028 * @author Juergen Hoeller
029 * @since 4.0
030 * @see org.springframework.context.i18n.LocaleContextHolder
031 */
032@UsesJava8
033public final class DateTimeContextHolder {
034
035        private static final ThreadLocal<DateTimeContext> dateTimeContextHolder =
036                        new NamedThreadLocal<DateTimeContext>("DateTimeContext");
037
038
039        /**
040         * Reset the DateTimeContext for the current thread.
041         */
042        public static void resetDateTimeContext() {
043                dateTimeContextHolder.remove();
044        }
045
046        /**
047         * Associate the given DateTimeContext with the current thread.
048         * @param dateTimeContext the current DateTimeContext,
049         * or {@code null} to reset the thread-bound context
050         */
051        public static void setDateTimeContext(DateTimeContext dateTimeContext) {
052                if (dateTimeContext == null) {
053                        resetDateTimeContext();
054                }
055                else {
056                        dateTimeContextHolder.set(dateTimeContext);
057                }
058        }
059
060        /**
061         * Return the DateTimeContext associated with the current thread, if any.
062         * @return the current DateTimeContext, or {@code null} if none
063         */
064        public static DateTimeContext getDateTimeContext() {
065                return dateTimeContextHolder.get();
066        }
067
068
069        /**
070         * Obtain a DateTimeFormatter with user-specific settings applied to the given base Formatter.
071         * @param formatter the base formatter that establishes default formatting rules
072         * (generally user independent)
073         * @param locale the current user locale (may be {@code null} if not known)
074         * @return the user-specific DateTimeFormatter
075         */
076        public static DateTimeFormatter getFormatter(DateTimeFormatter formatter, Locale locale) {
077                DateTimeFormatter formatterToUse = (locale != null ? formatter.withLocale(locale) : formatter);
078                DateTimeContext context = getDateTimeContext();
079                return (context != null ? context.getFormatter(formatterToUse) : formatterToUse);
080        }
081
082}