001 002 package railo.runtime.i18n; 003 004 import java.util.Arrays; 005 import java.util.Iterator; 006 import java.util.LinkedHashMap; 007 import java.util.Locale; 008 import java.util.Map; 009 import java.util.Map.Entry; 010 import java.util.regex.Matcher; 011 import java.util.regex.Pattern; 012 013 import railo.runtime.exp.ExpressionException; 014 import railo.runtime.type.util.ListUtil; 015 016 017 /** 018 * Factory to create Locales by CFML rules 019 */ 020 public final class LocaleFactory { 021 //private static Pattern localePattern = Pattern.compile("^\\s*([^\\s\\(]+)\\s*(\\(\\s*([^\\s\\)]+)\\s*\\))?\\s*$"); 022 private static Pattern localePattern = Pattern.compile("^\\s*([^\\(]+)\\s*(\\(\\s*([^\\)]+)\\s*\\))?\\s*$"); 023 private static Pattern localePattern2 = Pattern.compile("^([a-z]{2})_([a-z]{2,3})$"); 024 private static Pattern localePattern3 = Pattern.compile("^([a-z]{2})_([a-z]{2,3})_([a-z]{2,})$"); 025 026 private static Map<String,Locale> locales=new LinkedHashMap<String,Locale>(); 027 private static Map<String,Locale> localeAlias=new LinkedHashMap<String,Locale>(); 028 029 private static String list; 030 static { 031 Locale[] ls = Locale.getAvailableLocales(); 032 033 034 String key; 035 StringBuffer sb=new StringBuffer(); 036 for(int i=0;i<ls.length;i++) { 037 key=ls[i].getDisplayName(Locale.US).toLowerCase(); 038 locales.put(key, ls[i]); 039 if(key.indexOf(',')!=-1){ 040 key=ls[i].toString(); 041 //print.ln(key); 042 043 } 044 if(i>0)sb.append(","); 045 sb.append(key); 046 } 047 list=sb.toString(); 048 049 050 setLocalAlias("albanian (albania)", LocaleConstant.ALBANIAN_ALBANIA); 051 052 setLocalAlias("arabic (algeria)", LocaleConstant.ARABIC_ALGERIA); 053 setLocalAlias("arabic (bahrain)", LocaleConstant.ARABIC_BAHRAIN); 054 setLocalAlias("arabic (egypt)", LocaleConstant.ARABIC_EGYPT); 055 setLocalAlias("arabic (iraq)", LocaleConstant.ARABIC_IRAQ); 056 setLocalAlias("arabic (jordan)", LocaleConstant.ARABIC_JORDAN); 057 setLocalAlias("arabic (kuwait)", LocaleConstant.ARABIC_KUWAIT); 058 setLocalAlias("arabic (lebanon)", LocaleConstant.ARABIC_LEBANON); 059 setLocalAlias("arabic (libya)", LocaleConstant.ARABIC_LIBYA); 060 setLocalAlias("arabic (morocco)", LocaleConstant.ARABIC_MAROCCO); 061 setLocalAlias("arabic (oman)", LocaleConstant.ARABIC_OMAN); 062 setLocalAlias("arabic (qatar)", LocaleConstant.ARABIC_QATAR); 063 setLocalAlias("arabic (saudi arabia)", LocaleConstant.ARABIC_SAUDI_ARABIA); 064 setLocalAlias("arabic (sudan)", LocaleConstant.ARABIC_SUDAN); 065 setLocalAlias("arabic (syria)", LocaleConstant.ARABIC_SYRIA); 066 setLocalAlias("arabic (tunisia)", LocaleConstant.ARABIC_TUNISIA); 067 setLocalAlias("arabic (united arab emirates)", LocaleConstant.ARABIC_UNITED_ARAB_EMIRATES); 068 setLocalAlias("arabic (yemen)", LocaleConstant.ARABIC_YEMEN); 069 070 setLocalAlias("chinese (china)", Locale.CHINA); 071 setLocalAlias("chinese (hong kong)",LocaleConstant.CHINESE_HONG_KONG); 072 setLocalAlias("chinese (singapore)",LocaleConstant.CHINESE_SINGAPORE); 073 setLocalAlias("chinese (taiwan)",LocaleConstant.CHINESE_TAIWAN); 074 setLocalAlias("dutch (belgian)",LocaleConstant.DUTCH_BELGIUM); 075 setLocalAlias("dutch (belgium)",LocaleConstant.DUTCH_BELGIUM); 076 setLocalAlias("dutch (standard)",LocaleConstant.DUTCH_NETHERLANDS); 077 setLocalAlias("english (australian)",LocaleConstant.ENGLISH_AUSTRALIA); 078 setLocalAlias("english (australia)",LocaleConstant.ENGLISH_AUSTRALIA); 079 setLocalAlias("english (canadian)",LocaleConstant.ENGLISH_CANADA); 080 setLocalAlias("english (canada)",LocaleConstant.ENGLISH_CANADA); 081 setLocalAlias("english (new zealand)",LocaleConstant.ENGLISH_NEW_ZEALAND); 082 setLocalAlias("english (uk)",LocaleConstant.ENGLISH_UNITED_KINDOM); 083 setLocalAlias("english (united kingdom)",LocaleConstant.ENGLISH_UNITED_KINDOM); 084 setLocalAlias("english (gb)",LocaleConstant.ENGLISH_UNITED_KINDOM); 085 setLocalAlias("english (great britan)",LocaleConstant.ENGLISH_UNITED_KINDOM); 086 setLocalAlias("english (us)",LocaleConstant.ENGLISH_UNITED_STATES); 087 setLocalAlias("english (united states)",LocaleConstant.ENGLISH_UNITED_STATES); 088 setLocalAlias("english (united states of america)",LocaleConstant.ENGLISH_UNITED_STATES); 089 setLocalAlias("english (usa)",LocaleConstant.ENGLISH_UNITED_STATES); 090 setLocalAlias("french (belgium)",new Locale("fr","BE")); 091 setLocalAlias("french (belgian)",new Locale("fr","BE")); 092 setLocalAlias("french (canadian)",new Locale("fr","CA")); 093 setLocalAlias("french (canadia)",new Locale("fr","CA")); 094 setLocalAlias("french (standard)",new Locale("fr","FRA")); 095 setLocalAlias("french (swiss)",new Locale("fr","CH")); 096 setLocalAlias("german (austrian)",new Locale("de","AT")); 097 setLocalAlias("german (austria)",new Locale("de","AT")); 098 setLocalAlias("german (standard)",new Locale("de","DE")); 099 setLocalAlias("german (swiss)",new Locale("de","CH")); 100 setLocalAlias("italian (standard)",new Locale("it","IT")); 101 setLocalAlias("italian (swiss)",new Locale("it","CH")); 102 setLocalAlias("japanese",new Locale("ja","JP")); 103 setLocalAlias("korean",Locale.KOREAN); 104 setLocalAlias("norwegian (bokmal)",new Locale("no","NO")); 105 setLocalAlias("norwegian (nynorsk)",new Locale("no","NO")); 106 setLocalAlias("portuguese (brazilian)",LocaleConstant.PORTUGUESE_BRASIL); 107 setLocalAlias("portuguese (brazil)",LocaleConstant.PORTUGUESE_BRASIL); 108 setLocalAlias("portuguese (standard)",LocaleConstant.PORTUGUESE_PORTUGAL); 109 setLocalAlias("rhaeto-romance (swiss)",new Locale("rm","CH")); 110 locales.put("rhaeto-romance (swiss)",new Locale("rm","CH")); 111 setLocalAlias("spanish (modern)",new Locale("es","ES")); 112 setLocalAlias("spanish (standard)",new Locale("es","ES")); 113 setLocalAlias("swedish",new Locale("sv","SE")); 114 } 115 116 private LocaleFactory(){} 117 118 private static void setLocalAlias(String name, Locale locale) { 119 if(!localeAlias.containsKey(name))localeAlias.put(name, locale); 120 } 121 122 /** 123 * @param strLocale 124 * @param defaultValue 125 * @return return locale match to String 126 */ 127 public static Locale getLocale(String strLocale, Locale defaultValue) { 128 try { 129 return getLocale(strLocale); 130 } catch (ExpressionException e) { 131 return defaultValue; 132 } 133 } 134 135 136 /** 137 * @param strLocale 138 * @return return locale match to String 139 * @throws ExpressionException 140 */ 141 public static Locale getLocale(String strLocale) throws ExpressionException { 142 String strLocaleLC = strLocale.toLowerCase().trim(); 143 Locale l=locales.get(strLocaleLC); 144 if(l!=null) return l; 145 146 l=localeAlias.get(strLocaleLC); 147 if(l!=null) return l; 148 149 Matcher matcher = localePattern2.matcher(strLocaleLC); 150 if(matcher.find()) { 151 int len=matcher.groupCount(); 152 if(len==2) { 153 String lang=matcher.group(1).trim(); 154 String country=matcher.group(2).trim(); 155 Locale locale=new Locale(lang,country); 156 157 try { 158 locale.getISO3Language(); 159 setLocalAlias(strLocaleLC, locale); 160 return locale; 161 } 162 catch(Exception e) {} 163 } 164 } 165 166 matcher = localePattern3.matcher(strLocaleLC); 167 if(matcher.find()) { 168 int len=matcher.groupCount(); 169 if(len==3) { 170 String lang=matcher.group(1).trim(); 171 String country=matcher.group(2).trim(); 172 String variant=matcher.group(3).trim(); 173 Locale locale=new Locale(lang,country,variant); 174 175 try { 176 locale.getISO3Language(); 177 setLocalAlias(strLocaleLC, locale); 178 return locale; 179 } 180 catch(Exception e) {} 181 } 182 } 183 184 185 matcher=localePattern.matcher(strLocaleLC); 186 if(matcher.find()) { 187 int len=matcher.groupCount(); 188 189 if(len==3) { 190 191 String lang=matcher.group(1).trim(); 192 String country=matcher.group(3); 193 if(country!=null)country=country.trim(); 194 Object objLocale=null; 195 196 if(country!=null) objLocale=locales.get(lang.toLowerCase()+" ("+(country.toLowerCase())+")"); 197 else objLocale=locales.get(lang.toLowerCase()); 198 if(objLocale!=null)return (Locale)objLocale; 199 200 Locale locale; 201 if(country!=null)locale=new Locale(lang.toUpperCase(),country.toLowerCase()); 202 else locale=new Locale(lang); 203 204 try { 205 locale.getISO3Language(); 206 } 207 catch(Exception e) { 208 if(strLocale.indexOf('-')!=-1) return getLocale(strLocale.replace('-', '_')); 209 throw new ExpressionException("unsupported Locale ["+strLocale+"]","supported Locales are:"+getSupportedLocalesAsString()); 210 } 211 setLocalAlias(strLocaleLC, locale); 212 return locale; 213 214 } 215 } 216 217 218 throw new ExpressionException("can't cast value ("+strLocale+") to a Locale","supported Locales are:"+getSupportedLocalesAsString()); 219 } 220 221 222 private static String getSupportedLocalesAsString() { 223 //StringBuffer sb=new StringBuffer(); 224 // TODO chnge from ArryObject to string 225 String[] arr = locales.keySet().toArray(new String[locales.size()]); 226 Arrays.sort(arr); 227 return ListUtil.arrayToList(arr,","); 228 229 } 230 231 /** 232 * @param locale 233 * @return cast a Locale to a String 234 */ 235 public static String toString(Locale locale) { 236 String lang=locale.getLanguage(); 237 String country=locale.getCountry(); 238 239 synchronized(localeAlias){ 240 Iterator<Entry<String, Locale>> it = localeAlias.entrySet().iterator(); 241 Map.Entry<String, Locale> entry; 242 while(it.hasNext()) { 243 entry= it.next(); 244 //Object qkey=it.next(); 245 Locale curr=entry.getValue(); 246 if(lang.equals(curr.getLanguage()) && country.equals(curr.getCountry())) { 247 return entry.getKey().toString(); 248 } 249 } 250 } 251 return locale.getDisplayName(Locale.ENGLISH); 252 } 253 254 /** 255 * @return Returns the locales. 256 */ 257 public static Map getLocales() { 258 return locales; 259 } 260 public static String getLocaleList() { 261 return list; 262 } 263 }