KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jahia > utils > LanguageCodeConverters


1 package org.jahia.utils;
2
3 import java.util.Locale JavaDoc;
4 import java.util.StringTokenizer JavaDoc;
5 import java.text.Collator JavaDoc;
6 import java.util.Comparator JavaDoc;
7 import java.util.ArrayList JavaDoc;
8 import java.util.Collections JavaDoc;
9
10 /**
11  * <p>Title: Utility class to convert between the different type of language
12  * codes encodings.</p>
13  * <p>Description: This class was design to offer conversion tools between
14  * various language code encodings into Strings, Locales and other types of
15  * objects. </p>
16  * <p>Copyright: Copyright (c) 2002</p>
17  * <p>Company: </p>
18  * @author Serge Huber.
19  * @version 1.0
20  */

21
22 public class LanguageCodeConverters {
23
24     /**
25      * Converts string such as
26      * en_US, fr_CH_unix, fr, en, _GB, fr__UNIX
27      * into Locale objects. This method is the reverse operation of the
28      * Locale.toString() output. So a good test case for this method could
29      * be :
30      * languageCodeToLocale(Locale.toString()).equals(Locale)
31      * @param languageCode the encoded string
32      * @return the resulting Locale object, or the default language code if
33      * no language was found.
34      */

35     public static Locale JavaDoc languageCodeToLocale(String JavaDoc languageCode) {
36         if ( languageCode == null ){
37             return null;
38         }
39         StringTokenizer JavaDoc codeTokens = new StringTokenizer JavaDoc(languageCode,"_");
40         String JavaDoc language = "";
41         String JavaDoc country = "";
42         String JavaDoc variant = "";
43
44         if (codeTokens.hasMoreTokens()) {
45             language = codeTokens.nextToken();
46         }
47         if (codeTokens.hasMoreTokens()) {
48             country = codeTokens.nextToken();
49         }
50         if (codeTokens.hasMoreTokens()) {
51             variant = codeTokens.nextToken();
52         }
53
54         return newLocale(language, country, variant);
55     }
56
57     /**
58      * Converts language tags encoded (RFC 3066) to Locales. Examples of
59      * language tags encoding are :
60      * en-us, en, en-scouse
61      * Warning : this is not entirely RFC 3066 because we cannot convert from
62      * 3 characters ISO 639 part 2 to ISO 639 part 1 codes. In the case a
63      * 3 characters code is found we return null.
64      * @param languageCode the encoded string
65      * @return a Locale corresponding to the encoding.
66      */

67     public static Locale JavaDoc languageTagsToLocale(String JavaDoc languageCode) {
68         StringTokenizer JavaDoc codeTokens = new StringTokenizer JavaDoc(languageCode,"-");
69         String JavaDoc language = "";
70         String JavaDoc country = "";
71         String JavaDoc variant = "";
72
73         String JavaDoc primaryTag = "";
74         String JavaDoc secondSubTag = "";
75         String JavaDoc thirdSubTag = "";
76
77         if (codeTokens.hasMoreTokens()) {
78             primaryTag = codeTokens.nextToken();
79         }
80         if (codeTokens.hasMoreTokens()) {
81             secondSubTag = codeTokens.nextToken();
82         }
83         if (codeTokens.hasMoreTokens()) {
84             thirdSubTag = codeTokens.nextToken();
85         }
86
87         // now we must determine what is a language, what is a dialect or
88
// a variant depending on RFC 3066's definitions.
89

90         // 1. let's analyse the primary sub tag to see if we can use it as
91
// a language
92
if (primaryTag.length() != 2) {
93             // language codes other than 2 characters are not supported for
94
// the moment.
95

96             // we could correct or reduce this problem by implementing a
97
// conversion table from ISO 639 part 2 (3-char) to ISO 639 part 1
98
// (2-char), but for the moment we don't.
99

100             /** @todo implement convertion from 3-char to 2-char for languages */
101             return null;
102         }
103         language = primaryTag;
104
105         // 2. the second tag can be either a country code if it's 2 characters
106
// long, or variant or dialect information.
107
if (secondSubTag.length() == 2) {
108             country = secondSubTag;
109             variant = thirdSubTag;
110         } else {
111             variant = secondSubTag;
112         }
113
114         return newLocale(language, country, variant);
115     }
116
117     /**
118      * Returns a language tags encoded (RFC 3066) compliant string from
119      * a Java Locale object. Note that Locales without any languages will
120      * not be accepted by this method and will return a null String since
121      * language tags MUST contain a language
122      *
123      * @param locale the locale we want to be converted.
124      *
125      * @return a String containing the RFC 3066 encoded language information
126      * extracted from the tag. If their is no language found in the locale a
127      * NULL string is returned instead !
128      */

129     public static String JavaDoc localeToLanguageTag(Locale JavaDoc locale) {
130         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
131         if (!("".equals(locale.getLanguage()))) {
132             result.append(locale.getLanguage());
133         } else {
134             // if there is no language we can't return a valid
135
// language tag.
136
return null;
137         }
138         if (!("".equals(locale.getCountry()))) {
139             result.append("-");
140             result.append(locale.getCountry());
141         }
142         if (!("".equals(locale.getVariant()))) {
143             result.append("-");
144             result.append(locale.getVariant());
145         }
146
147         return result.toString();
148     }
149
150     /**
151      * A small helper method that allows the various parameters to be empty
152      * strings and always return valid locale objects. It mostly behaves likes
153      * the regular Locale constructor, except for the case where the language
154      * is empty that makes it return the default system Locale.
155      *
156      * @param language a 2-character ISO 639 part 1 compliant language code.
157      * If the language is empty then the default system locale
158      * will be returned.
159      * @param country a 2-character ISO 3166 compliant country code
160      * @param variant a String indicating the variant of the locale
161      * @return a valid locale object using the given parameters, or the default
162      * system locale if the language string was empty.
163      */

164     private static Locale JavaDoc newLocale(String JavaDoc language, String JavaDoc country, String JavaDoc variant) {
165         if ("".equals(variant)) {
166             if ("".equals(country)) {
167                 if ("".equals(language)) {
168                     return Locale.getDefault();
169                 } else {
170                     return new Locale JavaDoc(language, "");
171                 }
172             } else {
173                 return new Locale JavaDoc(language, country);
174             }
175         } else {
176             return new Locale JavaDoc(language, country, variant);
177         }
178     }
179
180     public static ArrayList JavaDoc getSortedLocaleList(Locale JavaDoc currentLocale) {
181         Locale JavaDoc[] availableLocales = Locale.getAvailableLocales();
182         ArrayList JavaDoc sortedLocaleList = new ArrayList JavaDoc();
183         for (int i=0; i < availableLocales.length; i++) {
184           Locale JavaDoc curLocale = availableLocales[i];
185           sortedLocaleList.add(curLocale);
186         }
187         Collections.sort(sortedLocaleList, LanguageCodeConverters.getLocaleDisplayNameComparator(currentLocale));
188         return sortedLocaleList;
189     }
190
191     /**
192      * Comparator implementation that compares locale display names in a certain
193      * current locale.
194      */

195     public static class LocaleDisplayNameComparator implements Comparator JavaDoc {
196
197         private Collator JavaDoc collator = Collator.getInstance();
198         private Locale JavaDoc currentLocale;
199
200         public LocaleDisplayNameComparator(Locale JavaDoc locale) {
201             if (locale != null) {
202                 this.currentLocale = locale;
203                 collator = Collator.getInstance(locale);
204             }
205         }
206
207         public int compare(Object JavaDoc o1,
208                    Object JavaDoc o2) {
209             Locale JavaDoc locale1 = (Locale JavaDoc) o1;
210             Locale JavaDoc locale2 = (Locale JavaDoc) o2;
211             return collator.compare(locale1.getDisplayName(currentLocale), locale2.getDisplayName(currentLocale));
212         }
213
214         public boolean equals(Object JavaDoc obj) {
215             if (obj instanceof LocaleDisplayNameComparator) {
216                 return true;
217             } else {
218                 return false;
219             }
220         }
221     }
222
223     public static LocaleDisplayNameComparator getLocaleDisplayNameComparator(Locale JavaDoc locale) {
224         return new LocaleDisplayNameComparator(locale);
225     }
226
227 }
Popular Tags