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.joda;
018
019import java.util.Locale;
020
021import org.joda.time.format.DateTimeFormatter;
022
023import org.springframework.core.NamedThreadLocal;
024
025/**
026 * A holder for a thread-local {@link JodaTimeContext}
027 * with user-specific Joda-Time settings.
028 *
029 * @author Keith Donald
030 * @author Juergen Hoeller
031 * @since 3.0
032 * @see org.springframework.context.i18n.LocaleContextHolder
033 */
034public final class JodaTimeContextHolder {
035
036        private static final ThreadLocal<JodaTimeContext> jodaTimeContextHolder =
037                        new NamedThreadLocal<JodaTimeContext>("JodaTimeContext");
038
039
040        /**
041         * Reset the JodaTimeContext for the current thread.
042         */
043        public static void resetJodaTimeContext() {
044                jodaTimeContextHolder.remove();
045        }
046
047        /**
048         * Associate the given JodaTimeContext with the current thread.
049         * @param jodaTimeContext the current JodaTimeContext,
050         * or {@code null} to reset the thread-bound context
051         */
052        public static void setJodaTimeContext(JodaTimeContext jodaTimeContext) {
053                if (jodaTimeContext == null) {
054                        resetJodaTimeContext();
055                }
056                else {
057                        jodaTimeContextHolder.set(jodaTimeContext);
058                }
059        }
060
061        /**
062         * Return the JodaTimeContext associated with the current thread, if any.
063         * @return the current JodaTimeContext, or {@code null} if none
064         */
065        public static JodaTimeContext getJodaTimeContext() {
066                return jodaTimeContextHolder.get();
067        }
068
069
070        /**
071         * Obtain a DateTimeFormatter with user-specific settings applied to the given base Formatter.
072         * @param formatter the base formatter that establishes default formatting rules
073         * (generally user independent)
074         * @param locale the current user locale (may be {@code null} if not known)
075         * @return the user-specific DateTimeFormatter
076         */
077        public static DateTimeFormatter getFormatter(DateTimeFormatter formatter, Locale locale) {
078                DateTimeFormatter formatterToUse = (locale != null ? formatter.withLocale(locale) : formatter);
079                JodaTimeContext context = getJodaTimeContext();
080                return (context != null ? context.getFormatter(formatterToUse) : formatterToUse);
081        }
082
083}