1 package org.apache.turbine.util;
2
3 import java.nio.charset.Charset;
4 import java.nio.charset.IllegalCharsetNameException;
5 import java.nio.charset.StandardCharsets;
6 import java.nio.charset.UnsupportedCharsetException;
7
8 /*
9 * Licensed to the Apache Software Foundation (ASF) under one
10 * or more contributor license agreements. See the NOTICE file
11 * distributed with this work for additional information
12 * regarding copyright ownership. The ASF licenses this file
13 * to you under the Apache License, Version 2.0 (the
14 * "License"); you may not use this file except in compliance
15 * with the License. You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing,
20 * software distributed under the License is distributed on an
21 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22 * KIND, either express or implied. See the License for the
23 * specific language governing permissions and limitations
24 * under the License.
25 */
26
27 import java.util.Locale;
28
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.fulcrum.mimetype.MimeTypeService;
31 import org.apache.logging.log4j.LogManager;
32 import org.apache.logging.log4j.Logger;
33 import org.apache.turbine.Turbine;
34 import org.apache.turbine.TurbineConstants;
35 import org.apache.turbine.services.ServiceManager;
36 import org.apache.turbine.services.TurbineServices;
37 /*
38 * Licensed to the Apache Software Foundation (ASF) under one
39 * or more contributor license agreements. See the NOTICE file
40 * distributed with this work for additional information
41 * regarding copyright ownership. The ASF licenses this file
42 * to you under the Apache License, Version 2.0 (the
43 * "License"); you may not use this file except in compliance
44 * with the License. You may obtain a copy of the License at
45 *
46 * http://www.apache.org/licenses/LICENSE-2.0
47 *
48 * Unless required by applicable law or agreed to in writing,
49 * software distributed under the License is distributed on an
50 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
51 * KIND, either express or implied. See the License for the
52 * specific language governing permissions and limitations
53 * under the License.
54 */
55
56 /**
57 * This class provides utilities for handling locales and charsets
58 *
59 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
60 */
61 public class LocaleUtils
62 {
63 /** Logging */
64 private static final Logger log = LogManager.getLogger(LocaleUtils.class);
65
66 /** The default locale. */
67 private static Locale defaultLocale = null;
68
69 /** The default charset. */
70 private static Charset defaultCharSet = null;
71
72 /**
73 * Returns the default input encoding for the servlet.
74 *
75 * @return the default input encoding.
76 */
77 public static String getDefaultInputEncoding()
78 {
79 // Get the default input defaultEncoding
80 String inputEncoding = Turbine.getConfiguration()
81 .getString(TurbineConstants.PARAMETER_ENCODING_KEY,
82 TurbineConstants.PARAMETER_ENCODING_DEFAULT);
83
84 log.debug("Input Encoding has been set to {}", inputEncoding);
85
86 return inputEncoding;
87 }
88
89 /**
90 * Gets the default locale defined by properties named "locale.default.lang"
91 * and "locale.default.country".
92 *
93 * This changed from earlier Turbine versions that you can rely on
94 * getDefaultLocale() to never return null.
95 *
96 * @return A Locale object.
97 */
98 public static Locale getDefaultLocale()
99 {
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 }