001 /* 002 * Copyright 2001-2011 Stephen Colebourne 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 * http://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 package org.joda.time.tz; 017 018 import java.text.DateFormatSymbols; 019 import java.util.HashMap; 020 import java.util.Locale; 021 import java.util.Map; 022 023 import org.joda.time.DateTimeUtils; 024 025 /** 026 * The default name provider acquires localized names from 027 * {@link DateFormatSymbols java.text.DateFormatSymbols}. 028 * <p> 029 * DefaultNameProvider is thread-safe and immutable. 030 * 031 * @author Brian S O'Neill 032 * @since 1.0 033 */ 034 @SuppressWarnings("unchecked") 035 public class DefaultNameProvider implements NameProvider { 036 // locale -> (id -> (nameKey -> [shortName, name])) 037 private HashMap<Locale, Map<String, Map<String, Object>>> iByLocaleCache = createCache(); 038 039 public DefaultNameProvider() { 040 } 041 042 public String getShortName(Locale locale, String id, String nameKey) { 043 String[] nameSet = getNameSet(locale, id, nameKey); 044 return nameSet == null ? null : nameSet[0]; 045 } 046 047 public String getName(Locale locale, String id, String nameKey) { 048 String[] nameSet = getNameSet(locale, id, nameKey); 049 return nameSet == null ? null : nameSet[1]; 050 } 051 052 private synchronized String[] getNameSet(Locale locale, String id, String nameKey) { 053 if (locale == null || id == null || nameKey == null) { 054 return null; 055 } 056 057 Map<String, Map<String, Object>> byIdCache = iByLocaleCache.get(locale); 058 if (byIdCache == null) { 059 iByLocaleCache.put(locale, byIdCache = createCache()); 060 } 061 062 Map<String, Object> byNameKeyCache = byIdCache.get(id); 063 if (byNameKeyCache == null) { 064 byIdCache.put(id, byNameKeyCache = createCache()); 065 066 String[][] zoneStringsEn = DateTimeUtils.getDateFormatSymbols(Locale.ENGLISH).getZoneStrings(); 067 String[] setEn = null; 068 for (String[] strings : zoneStringsEn) { 069 if (strings != null && strings.length == 5 && id.equals(strings[0])) { 070 setEn = strings; 071 break; 072 } 073 } 074 String[][] zoneStringsLoc = DateTimeUtils.getDateFormatSymbols(locale).getZoneStrings(); 075 String[] setLoc = null; 076 for (String[] strings : zoneStringsLoc) { 077 if (strings != null && strings.length == 5 && id.equals(strings[0])) { 078 setLoc = strings; 079 break; 080 } 081 } 082 083 if (setEn != null && setLoc != null) { 084 byNameKeyCache.put(setEn[2], new String[] {setLoc[2], setLoc[1]}); 085 // need to handle case where summer and winter have the same 086 // abbreviation, such as EST in Australia [1716305] 087 // we handle this by appending "-Summer", cf ZoneInfoCompiler 088 if (setEn[2].equals(setEn[4])) { 089 byNameKeyCache.put(setEn[4] + "-Summer", new String[] {setLoc[4], setLoc[3]}); 090 } else { 091 byNameKeyCache.put(setEn[4], new String[] {setLoc[4], setLoc[3]}); 092 } 093 } 094 } 095 return (String[]) byNameKeyCache.get(nameKey); 096 } 097 098 private HashMap createCache() { 099 return new HashMap(7); 100 } 101 }