1bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor/*
2bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *  Licensed to the Apache Software Foundation (ASF) under one or more
3bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *  contributor license agreements.  See the NOTICE file distributed with
4bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *  this work for additional information regarding copyright ownership.
5bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *  The ASF licenses this file to You under the Apache License, Version 2.0
6bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *  (the "License"); you may not use this file except in compliance with
7bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *  the License.  You may obtain a copy of the License at
8bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *
9bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *     http://www.apache.org/licenses/LICENSE-2.0
10bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *
11bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *  Unless required by applicable law or agreed to in writing, software
12bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *  distributed under the License is distributed on an "AS IS" BASIS,
13bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *  See the License for the specific language governing permissions and
15bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor *  limitations under the License.
16bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor */
17bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor
18bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnorpackage org.apache.harmony.luni.util;
19bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor
20bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnorimport java.text.NumberFormat;
21bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnorimport java.text.DecimalFormatSymbols;
22bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnorimport java.util.Locale;
23bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor
24bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor/**
25bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor * Manages a locale-specific thread-local cache of expensive locale-specific
26bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor * format objects.  The objects are discarded if the locale requested changes,
27bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor * or if heap space is exhausted.
28bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor */
29bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnorpublic class LocaleCache {
30bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor
31bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor    private static final ThreadLocalCache<LocaleCache> cache = new ThreadLocalCache<LocaleCache>();
32bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor
33bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor    private NumberFormat numberFormat = null;
34bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor
35bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor    private final Locale locale;
36bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor
37bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor    private LocaleCache(Locale locale) {
38bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor        this.locale = locale;
39bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor    }
40bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor
41bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor    /**
42bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor     * Re-uses or creates a LocaleCache object for the specified Locale.
43bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor     * LocaleCache objects are reused within a thread as long as they have
44bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor     * the same Locale (which must not be null).
45bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor     */
46bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor    private static LocaleCache getLocaleCache(Locale locale) {
47bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor        LocaleCache lc = cache.get();
48bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor        if (lc == null || !lc.locale.equals(locale)) {
49bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor            lc = new LocaleCache(locale);
50bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor            cache.set(lc);
51bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor        }
52bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor        return lc;
53bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor    }
54bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor
55bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor    /**
560dfef7bc223f18a1372b4c44c822b9cdc5d5f741Dan Egnor     * Returns a NumberFormat object for the specified Locale.
57bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor     */
58bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor    public static NumberFormat getNumberFormat(Locale locale) {
59bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor        LocaleCache lc = getLocaleCache(locale);
60bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor        if (lc.numberFormat == null) {
61bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor            lc.numberFormat = NumberFormat.getInstance(locale);
62bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor        }
630dfef7bc223f18a1372b4c44c822b9cdc5d5f741Dan Egnor
640dfef7bc223f18a1372b4c44c822b9cdc5d5f741Dan Egnor        // NumberFormat is mutable, so return a new clone each time.
650dfef7bc223f18a1372b4c44c822b9cdc5d5f741Dan Egnor        return (NumberFormat) lc.numberFormat.clone();
66bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor    }
67bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor}
68