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.List; 015 016 017 /** 018 * Factory to create Locales by Cold Fusion 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("chinese (china)", Locale.CHINA); 051 setLocalAlias("chinese (china)", Locale.CHINA); 052 setLocalAlias("chinese (hong kong)",new Locale("zh","HK")); 053 setLocalAlias("chinese (taiwan)",new Locale("zho","TWN")); 054 setLocalAlias("dutch (belgian)",new Locale("nl","BE")); 055 setLocalAlias("dutch (belgium)",new Locale("nl","BE")); 056 setLocalAlias("dutch (standard)",new Locale("nl","NL")); 057 setLocalAlias("english (australian)",new Locale("en","AU")); 058 setLocalAlias("english (australia)",new Locale("en","AU")); 059 setLocalAlias("english (canadian)",new Locale("en","CA")); 060 setLocalAlias("english (canadia)",new Locale("en","CA")); 061 setLocalAlias("english (new zealand)",new Locale("en","NZ")); 062 setLocalAlias("english (uk)",new Locale("en","GB")); 063 setLocalAlias("english (united kingdom)",new Locale("en","GB")); 064 setLocalAlias("english (us)",new Locale("en","US")); 065 setLocalAlias("french (belgium)",new Locale("fr","BE")); 066 setLocalAlias("french (belgian)",new Locale("fr","BE")); 067 setLocalAlias("french (canadian)",new Locale("fr","CA")); 068 setLocalAlias("french (canadia)",new Locale("fr","CA")); 069 setLocalAlias("french (standard)",new Locale("fr","FRA")); 070 setLocalAlias("french (swiss)",new Locale("fr","CH")); 071 setLocalAlias("german (austrian)",new Locale("de","AT")); 072 setLocalAlias("german (austria)",new Locale("de","AT")); 073 setLocalAlias("german (standard)",new Locale("de","DE")); 074 setLocalAlias("german (swiss)",new Locale("de","CH")); 075 setLocalAlias("italian (standard)",new Locale("it","IT")); 076 setLocalAlias("italian (swiss)",new Locale("it","CH")); 077 setLocalAlias("japanese",new Locale("ja","JP")); 078 setLocalAlias("korean",Locale.KOREAN); 079 setLocalAlias("norwegian (bokmal)",new Locale("no","NO")); 080 setLocalAlias("norwegian (nynorsk)",new Locale("no","NO")); 081 setLocalAlias("portuguese (brazilian)",new Locale("pt","BR")); 082 setLocalAlias("portuguese (brazil)",new Locale("pt","BR")); 083 setLocalAlias("portuguese (standard)",new Locale("pt")); 084 setLocalAlias("rhaeto-romance (swiss)",new Locale("rm","CH")); 085 locales.put("rhaeto-romance (swiss)",new Locale("rm","CH")); 086 setLocalAlias("spanish (modern)",new Locale("es","ES")); 087 setLocalAlias("spanish (standard)",new Locale("es","ES")); 088 setLocalAlias("swedish",new Locale("sv","SE")); 089 090 } 091 092 private LocaleFactory(){} 093 094 private static void setLocalAlias(String name, Locale locale) { 095 if(!localeAlias.containsKey(name))localeAlias.put(name, locale); 096 } 097 098 /** 099 * @param strLocale 100 * @param defaultValue 101 * @return return locale match to String 102 */ 103 public static Locale getLocale(String strLocale, Locale defaultValue) { 104 try { 105 return getLocale(strLocale); 106 } catch (ExpressionException e) { 107 return defaultValue; 108 } 109 } 110 111 112 /** 113 * @param strLocale 114 * @return return locale match to String 115 * @throws ExpressionException 116 */ 117 public static Locale getLocale(String strLocale) throws ExpressionException { 118 String strLocaleLC = strLocale.toLowerCase().trim(); 119 Locale l=(Locale) locales.get(strLocaleLC); 120 if(l!=null) return l; 121 122 l=(Locale) localeAlias.get(strLocaleLC); 123 if(l!=null) return l; 124 125 Matcher matcher = localePattern2.matcher(strLocaleLC); 126 if(matcher.find()) { 127 int len=matcher.groupCount(); 128 if(len==2) { 129 String lang=matcher.group(1).trim(); 130 String country=matcher.group(2).trim(); 131 Locale locale=new Locale(lang,country); 132 133 try { 134 locale.getISO3Language(); 135 setLocalAlias(strLocaleLC, locale); 136 return locale; 137 } 138 catch(Exception e) {} 139 } 140 } 141 142 matcher = localePattern3.matcher(strLocaleLC); 143 if(matcher.find()) { 144 int len=matcher.groupCount(); 145 if(len==3) { 146 String lang=matcher.group(1).trim(); 147 String country=matcher.group(2).trim(); 148 String variant=matcher.group(3).trim(); 149 Locale locale=new Locale(lang,country,variant); 150 151 try { 152 locale.getISO3Language(); 153 setLocalAlias(strLocaleLC, locale); 154 return locale; 155 } 156 catch(Exception e) {} 157 } 158 } 159 160 161 matcher=localePattern.matcher(strLocaleLC); 162 if(matcher.find()) { 163 int len=matcher.groupCount(); 164 165 if(len==3) { 166 167 String lang=matcher.group(1).trim(); 168 String country=matcher.group(3); 169 if(country!=null)country=country.trim(); 170 Object objLocale=null; 171 172 if(country!=null) objLocale=locales.get(lang.toLowerCase()+" ("+(country.toLowerCase())+")"); 173 else objLocale=locales.get(lang.toLowerCase()); 174 if(objLocale!=null)return (Locale)objLocale; 175 176 Locale locale; 177 if(country!=null)locale=new Locale(lang.toUpperCase(),country.toLowerCase()); 178 else locale=new Locale(lang); 179 180 try { 181 locale.getISO3Language(); 182 } 183 catch(Exception e) { 184 if(strLocale.indexOf('-')!=-1) return getLocale(strLocale.replace('-', '_')); 185 throw new ExpressionException("unsupported Locale ["+strLocale+"]","supported Locales are:"+getSupportedLocalesAsString()); 186 } 187 setLocalAlias(strLocaleLC, locale); 188 return locale; 189 190 } 191 } 192 193 194 throw new ExpressionException("can't cast value ("+strLocale+") to a Locale","supported Locales are:"+getSupportedLocalesAsString()); 195 } 196 197 198 private static String getSupportedLocalesAsString() { 199 //StringBuffer sb=new StringBuffer(); 200 // TODO chnge from ArryObject to string 201 String[] arr = (String[])locales.keySet().toArray(new String[locales.size()]); 202 Arrays.sort(arr); 203 return List.arrayToList(arr,","); 204 205 } 206 207 /** 208 * @param locale 209 * @return cast a Locale to a String 210 */ 211 public static String toString(Locale locale) { 212 String lang=locale.getLanguage(); 213 String country=locale.getCountry(); 214 215 synchronized(localeAlias){ 216 Iterator<Entry<String, Locale>> it = localeAlias.entrySet().iterator(); 217 Map.Entry<String, Locale> entry; 218 while(it.hasNext()) { 219 entry= it.next(); 220 //Object qkey=it.next(); 221 Locale curr=(Locale) entry.getValue(); 222 if(lang.equals(curr.getLanguage()) && country.equals(curr.getCountry())) { 223 return entry.getKey().toString(); 224 } 225 } 226 } 227 return locale.getDisplayName(Locale.ENGLISH); 228 } 229 230 /** 231 * @return Returns the locales. 232 */ 233 public static Map getLocales() { 234 return locales; 235 } 236 public static String getLocaleList() { 237 return list; 238 } 239 }