001 /*
002 Copyright (c) 1996-2011, Damon Hart-Davis
003 All rights reserved.
004
005 Redistribution and use in source and binary forms, with or without
006 modification, are permitted provided that the following conditions are
007 met:
008
009 * Redistributions of source code must retain the above copyright
010 notice, this list of conditions and the following disclaimer.
011
012 * Redistributions in binary form must reproduce the above copyright
013 notice, this list of conditions and the following disclaimer in the
014 documentation and/or other materials provided with the
015 distribution.
016
017 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
018 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
019 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
020 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
021 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
022 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
024 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
025 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
027 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028 */
029
030 package org.hd.d.pg2k.svrCore;
031
032 import java.util.ArrayList;
033 import java.util.Collections;
034 import java.util.HashMap;
035 import java.util.HashSet;
036 import java.util.List;
037 import java.util.Locale;
038 import java.util.Map;
039 import java.util.Set;
040
041 import org.hd.d.pg2k.svrCore.location.GeoUtils;
042
043 /**
044 * Created by IntelliJ IDEA.
045 * User: Damon Hart-Davis
046 * Date: 14-Sep-2003
047 * Time: 20:02:02
048 */
049
050 /**Holds constants and some utility methods for internationalisation (i18n).
051 * These are features common to the core system, Web presentation, etc.
052 */
053 public final class I18NTools
054 {
055 /**Name of common resource bundle for core i18n messages. */
056 public static final String BUNDLE_COMMON = "common";
057
058 /**Name of tree-description i18n resource bundle. */
059 public static final String BUNDLE_TREEDESC = "treedesc";
060
061 /**Default locale to use in the system and on the Web site.
062 * This is British English, and reflects what we expect to
063 * find in the base messages (files) that the Web sites
064 * will use.
065 * <p>
066 * This locale is one that we should always be able to support.
067 */
068 public static final Locale DEFAULT_SYSTEM_LOCALE = new Locale("en", "GB");
069
070 /**Main locales that we support i18n for in an immutable List.
071 * Earlier items are preferred (eg more commonly used by visitors);
072 * the site default is the first value.
073 * <p>
074 * Every item in this list is a Locale whose String version is of the form
075 * <tt>ll</tt> or <tt>ll_CC</tt>
076 * where "ll" is the language and "CC" the optional country code,
077 * eg <tt>fr</tt> for French and <tt>en_GB</tt> for UK English.
078 * <p>
079 * Every item that appears in this list has at least:
080 * <ul>
081 * <li>Most or all of the common message catalogue translated.
082 * <li>A standard flag icon.
083 * </ul>
084 * <p>
085 * There may be partial support for languages/locales other than those
086 * listed here.
087 */
088 public static final List<Locale> MAIN_LOCALES;
089
090 /**Initialise MAIN_LOCALES. */
091 static
092 {
093 final List<Locale> l = new ArrayList<Locale>();
094
095 // Default system value is first.
096 l.add(DEFAULT_SYSTEM_LOCALE); // Some variety of English (en).
097
098 // Then other (hopefully) well-supported locales
099 // in approximate descending order of use by visitors.
100 // List should be kept as small as possible since
101 // each extra choice consumes bandwidth and space on most pages,
102 // and, for example, we have very limited space on handheld/mobile devices.
103 l.add(new Locale("de", ""));
104 l.add(new Locale("es", ""));
105 //l.add(new Locale("zh", "CN")); // Decommissioned cn-bj1 2009/04/12.
106
107 MAIN_LOCALES = Collections.unmodifiableList(l);
108 }
109
110 /**Immutable map from (a small set of common) top-level ccTLDs to best overall locale in our supported set for that location.
111 * This is not comprehensive
112 * (though we try to cover common cases where we have any explicit support),
113 * and is mainly to help when a browser (or search engine) does not indicate
114 * a preferred locale explicitly.
115 */
116 public static final Map<GeoUtils.CCTLD, Locale> LOCALE_BY_CCTLD;
117
118 /**Initialise LOCALE_BY_CCTLD. */
119 static
120 {
121 // We use a HashMap for lookup speed.
122 final Map<GeoUtils.CCTLD, Locale> m = new HashMap<GeoUtils.CCTLD, Locale>(31);
123
124 m.put(MemoryTools.intern(new GeoUtils.CCTLD("uk")), new Locale("en", "GB")); // Default.
125 m.put(MemoryTools.intern(new GeoUtils.CCTLD("us")), new Locale("en", "US")); // Where most users with no language set in their browsers are from.
126 m.put(MemoryTools.intern(new GeoUtils.CCTLD("ca")), new Locale("en", "CA"));
127 m.put(MemoryTools.intern(new GeoUtils.CCTLD("au")), new Locale("en", "AU"));
128 m.put(MemoryTools.intern(new GeoUtils.CCTLD("nz")), new Locale("en", "NZ"));
129 m.put(MemoryTools.intern(new GeoUtils.CCTLD("za")), new Locale("en", "ZA"));
130 m.put(MemoryTools.intern(new GeoUtils.CCTLD("in")), new Locale("en", "IN"));
131
132 m.put(MemoryTools.intern(new GeoUtils.CCTLD("cn")), new Locale("zh", "CN"));
133 m.put(MemoryTools.intern(new GeoUtils.CCTLD("tw")), new Locale("zh", "TW"));
134 m.put(MemoryTools.intern(new GeoUtils.CCTLD("hk")), new Locale("zh", "HK"));
135
136 m.put(MemoryTools.intern(new GeoUtils.CCTLD("nl")), new Locale("nl", ""));
137 m.put(MemoryTools.intern(new GeoUtils.CCTLD("fr")), new Locale("fr", ""));
138 m.put(MemoryTools.intern(new GeoUtils.CCTLD("de")), new Locale("de", ""));
139 m.put(MemoryTools.intern(new GeoUtils.CCTLD("at")), new Locale("de", "AT"));
140 m.put(MemoryTools.intern(new GeoUtils.CCTLD("es")), new Locale("es", ""));
141 m.put(MemoryTools.intern(new GeoUtils.CCTLD("mx")), new Locale("es", "MX"));
142 m.put(MemoryTools.intern(new GeoUtils.CCTLD("it")), new Locale("it", ""));
143 m.put(MemoryTools.intern(new GeoUtils.CCTLD("jp")), new Locale("ja", ""));
144
145 m.put(MemoryTools.intern(new GeoUtils.CCTLD("mt")), new Locale("mt", ""));
146
147 LOCALE_BY_CCTLD = Collections.unmodifiableMap(m);
148 }
149
150
151 /**Immutable Set of most locales supported by the system.
152 * Designed for relatively fast lookup.
153 */
154 public static final Set<Locale> LOCALES;
155
156 /**Initialise LOCALES. */
157 static
158 {
159 // final TreeSet<Locale> s = new TreeSet<Locale>(new Comparator<Locale>(){
160 // /**Compares its two arguments for order.
161 // * Sorts in toString() order, but is designed to be fairly fast.
162 // */
163 // public int compare(final Locale locale1, final Locale locale2)
164 // {
165 // // For speed, do initial compare on language component
166 // // which avoids contructing new String values dynamically.
167 // final int llComp = locale1.getLanguage().compareTo(locale2.getLanguage());
168 // if(llComp != 0) { return(llComp); }
169 // // Total ordering on full String representation.
170 // return(locale1.toString().compareTo(locale2.toString()));
171 // }
172 // });
173
174 final HashSet<Locale> s = new HashSet<Locale>(2 * (MAIN_LOCALES.size() + LOCALE_BY_CCTLD.size()));
175 s.addAll(MAIN_LOCALES);
176 s.addAll(LOCALE_BY_CCTLD.values());
177
178 LOCALES = Collections.unmodifiableSet(s);
179 }
180 }