001package org.apache.turbine.util; 002 003import java.nio.charset.Charset; 004import java.nio.charset.IllegalCharsetNameException; 005import java.nio.charset.StandardCharsets; 006import java.nio.charset.UnsupportedCharsetException; 007 008/* 009 * Licensed to the Apache Software Foundation (ASF) under one 010 * or more contributor license agreements. See the NOTICE file 011 * distributed with this work for additional information 012 * regarding copyright ownership. The ASF licenses this file 013 * to you under the Apache License, Version 2.0 (the 014 * "License"); you may not use this file except in compliance 015 * with the License. You may obtain a copy of the License at 016 * 017 * http://www.apache.org/licenses/LICENSE-2.0 018 * 019 * Unless required by applicable law or agreed to in writing, 020 * software distributed under the License is distributed on an 021 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 022 * KIND, either express or implied. See the License for the 023 * specific language governing permissions and limitations 024 * under the License. 025 */ 026 027import java.util.Locale; 028 029import org.apache.commons.lang3.StringUtils; 030import org.apache.fulcrum.mimetype.MimeTypeService; 031import org.apache.logging.log4j.LogManager; 032import org.apache.logging.log4j.Logger; 033import org.apache.turbine.Turbine; 034import org.apache.turbine.TurbineConstants; 035import org.apache.turbine.services.ServiceManager; 036import org.apache.turbine.services.TurbineServices; 037/* 038 * Licensed to the Apache Software Foundation (ASF) under one 039 * or more contributor license agreements. See the NOTICE file 040 * distributed with this work for additional information 041 * regarding copyright ownership. The ASF licenses this file 042 * to you under the Apache License, Version 2.0 (the 043 * "License"); you may not use this file except in compliance 044 * with the License. You may obtain a copy of the License at 045 * 046 * http://www.apache.org/licenses/LICENSE-2.0 047 * 048 * Unless required by applicable law or agreed to in writing, 049 * software distributed under the License is distributed on an 050 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 051 * KIND, either express or implied. See the License for the 052 * specific language governing permissions and limitations 053 * under the License. 054 */ 055 056/** 057 * This class provides utilities for handling locales and charsets 058 * 059 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a> 060 */ 061public class LocaleUtils 062{ 063 /** Logging */ 064 private static final Logger log = LogManager.getLogger(LocaleUtils.class); 065 066 /** The default locale. */ 067 private static Locale defaultLocale = null; 068 069 /** The default charset. */ 070 private static Charset defaultCharSet = null; 071 072 /** 073 * Returns the default input encoding for the servlet. 074 * 075 * @return the default input encoding. 076 */ 077 public static String getDefaultInputEncoding() 078 { 079 // Get the default input defaultEncoding 080 String inputEncoding = Turbine.getConfiguration() 081 .getString(TurbineConstants.PARAMETER_ENCODING_KEY, 082 TurbineConstants.PARAMETER_ENCODING_DEFAULT); 083 084 log.debug("Input Encoding has been set to {}", inputEncoding); 085 086 return inputEncoding; 087 } 088 089 /** 090 * Gets the default locale defined by properties named "locale.default.lang" 091 * and "locale.default.country". 092 * 093 * This changed from earlier Turbine versions that you can rely on 094 * getDefaultLocale() to never return null. 095 * 096 * @return A Locale object. 097 */ 098 public static Locale getDefaultLocale() 099 { 100 if (defaultLocale == null) 101 { 102 /* Get the default locale and cache it in a static variable. */ 103 String lang = Turbine.getConfiguration() 104 .getString(TurbineConstants.LOCALE_DEFAULT_LANGUAGE_KEY, 105 TurbineConstants.LOCALE_DEFAULT_LANGUAGE_DEFAULT); 106 107 String country = Turbine.getConfiguration() 108 .getString(TurbineConstants.LOCALE_DEFAULT_COUNTRY_KEY, 109 TurbineConstants.LOCALE_DEFAULT_COUNTRY_DEFAULT); 110 111 // We ensure that lang and country is never null 112 defaultLocale = new Locale(lang, country); 113 } 114 115 return defaultLocale; 116 } 117 118 /** 119 * Gets the default charset defined by a property named 120 * "locale.default.charset" 121 * 122 * @return the name of the default charset or null. 123 */ 124 @Deprecated 125 public static String getDefaultCharSet() 126 { 127 return getDefaultCharset().name(); 128 } 129 130 /** 131 * Gets the default charset defined by a property named 132 * "locale.default.charset" 133 * 134 * @return the default charset, never null. 135 */ 136 public static Charset getDefaultCharset() 137 { 138 if (defaultCharSet == null) 139 { 140 /* Get the default charset and cache it in a static variable. */ 141 String charSet = Turbine.getConfiguration() 142 .getString(TurbineConstants.LOCALE_DEFAULT_CHARSET_KEY, 143 TurbineConstants.LOCALE_DEFAULT_CHARSET_DEFAULT); 144 145 if (StringUtils.isNotEmpty(charSet)) 146 { 147 defaultCharSet = charSetForName(charSet); 148 log.debug("defaultCharSet = {} (From Properties)", defaultCharSet); 149 } 150 } 151 152 Charset charset = defaultCharSet; 153 154 if (charset == null) // can happen if set explicitly in the configuration 155 { 156 log.debug("Default charset is empty!"); 157 /* Default charset isn't specified, get the locale specific one. */ 158 Locale locale = getDefaultLocale(); 159 log.debug("Locale is {}", locale); 160 161 if (!locale.equals(Locale.US)) 162 { 163 log.debug("We don't have US Locale!"); 164 ServiceManager serviceManager = TurbineServices.getInstance(); 165 if (serviceManager.isRegistered(MimeTypeService.ROLE)) 166 { 167 try 168 { 169 MimeTypeService mimeTypeService = (MimeTypeService) serviceManager.getService(MimeTypeService.ROLE); 170 charset = charSetForName(mimeTypeService.getCharSet(locale)); 171 } 172 catch (Exception e) 173 { 174 throw new RuntimeException(e); 175 } 176 177 log.debug("Charset now {}", charset); 178 } 179 } 180 181 // The fallback to end all fallbacks 182 if (charset == null) 183 { 184 charset = StandardCharsets.ISO_8859_1; 185 } 186 } 187 188 log.debug("Returning default Charset of {}", charset); 189 return charset; 190 } 191 192 /** 193 * Gets the charset defined by a property named "locale.override.charset" 194 * This property has no default. If it exists, the output charset is always 195 * set to its value 196 * 197 * @return the name of the override charset or null. 198 */ 199 @Deprecated 200 public static String getOverrideCharSet() 201 { 202 return Turbine.getConfiguration() 203 .getString(TurbineConstants.LOCALE_OVERRIDE_CHARSET_KEY); 204 } 205 206 /** 207 * Gets the charset defined by a property named "locale.override.charset" 208 * This property has no default. If it exists, the output charset is always 209 * set to its value 210 * 211 * @return the override charset or null. 212 */ 213 public static Charset getOverrideCharset() 214 { 215 String charset = Turbine.getConfiguration() 216 .getString(TurbineConstants.LOCALE_OVERRIDE_CHARSET_KEY); 217 218 if (StringUtils.isEmpty(charset)) 219 { 220 return null; 221 } 222 223 return charSetForName(charset); 224 } 225 226 /** 227 * Get a Charset object for a given name 228 * This method does not throw exceptions on illegal input but returns null. 229 * 230 * @param charSet the charset name 231 * 232 * @return the Charset or null if it does not exist 233 */ 234 private static Charset charSetForName(String charSet) 235 { 236 try 237 { 238 return Charset.forName(charSet); 239 } 240 catch (IllegalCharsetNameException | UnsupportedCharsetException e) 241 { 242 log.error("Illegal default charset {}", charSet); 243 } 244 245 return null; 246 } 247 248}