1
2
3
4
5 package org.rcfaces.core.internal.webapp;
6
7 import java.util.HashMap;
8 import java.util.HashSet;
9 import java.util.Locale;
10 import java.util.Map;
11 import java.util.Set;
12 import java.util.StringTokenizer;
13
14 import javax.servlet.ServletConfig;
15 import javax.servlet.ServletException;
16 import javax.servlet.http.HttpServletRequest;
17 import javax.servlet.http.HttpServletResponse;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.rcfaces.core.internal.Constants;
22 import org.rcfaces.core.internal.util.Delay;
23 import org.rcfaces.core.internal.util.ServletTools;
24
25
26
27
28
29 public class ConfiguredHttpServlet extends ExtendedHttpServlet {
30
31 private static final String REVISION = "$Revision: 1.18 $";
32
33 private static final long serialVersionUID = 8336388990583712944L;
34
35 private static final Log LOG = LogFactory
36 .getLog(ConfiguredHttpServlet.class);
37
38 public static final String USE_GZIP_PARAMETER = Constants
39 .getPackagePrefix()
40 + ".GZIP_SUPPORT";
41
42 private static final String EXPIRE_PARAMETER = Constants.getPackagePrefix()
43 + ".EXPIRES";
44
45 private static final String VERSIONED_EXPIRE_PARAMETER = Constants
46 .getPackagePrefix()
47 + ".VERSIONED_EXPIRES";
48
49 private static final String ETAG_SUPPORT_PARAMETER = Constants
50 .getPackagePrefix()
51 + ".ETAG_SUPPORT";
52
53 private static final String HASH_SUPPORT_PARAMETER = Constants
54 .getPackagePrefix()
55 + ".HASH_SUPPORT";
56
57 private static final String FILTERED_LOCALES_PARAMETER = Constants
58 .getPackagePrefix()
59 + ".FILTERED_LOCALES";
60
61 private static final String DEFAULT_LOCALE_PARAMETER = Constants
62 .getPackagePrefix()
63 + ".DEFAULT_LOCALE";
64
65 private static final String LOCALE_SUPPORT_PARAMETER = Constants
66 .getPackagePrefix()
67 + ".LOCALE_SUPPORT";
68
69 private static final String NONE_EXPIRATION_KEYWORD = "none";
70
71 private boolean gZipSupport;
72
73 private boolean etagSupport;
74
75 private boolean hashSupport;
76
77 private ExpirationDate expirationDate;
78
79 private ExpirationDate versionedExpirationDate;
80
81 private Set filtredLocales;
82
83 protected boolean localeSupport;
84
85 private final Map convertedLocales = new HashMap(32);
86
87 private Locale defaultLocale;
88
89 public void init(ServletConfig config) throws ServletException {
90
91 super.init(config);
92
93 String useGZIP = getParameter(USE_GZIP_PARAMETER);
94 if ("true".equalsIgnoreCase(useGZIP)) {
95 gZipSupport = true;
96
97 LOG.info("Enable gzip support for sevlet '" + getServletName()
98 + "'");
99 } else if ("false".equalsIgnoreCase(useGZIP)) {
100 gZipSupport = false;
101
102 LOG.info("Disable gzip support for sevlet '" + getServletName()
103 + "'");
104 } else {
105 gZipSupport = getDefaultGZipSupport();
106
107 LOG.info("Use default gzip support configuration (value="
108 + this.gZipSupport + ") for sevlet '" + getServletName()
109 + "'");
110 }
111
112 String etagSupport = getParameter(ETAG_SUPPORT_PARAMETER);
113 if ("true".equalsIgnoreCase(etagSupport)) {
114 this.etagSupport = true;
115
116 LOG.info("Enable etag support for sevlet '" + getServletName()
117 + "'");
118
119 } else if ("false".equalsIgnoreCase(etagSupport)) {
120 this.etagSupport = false;
121
122 LOG.info("Disable etag support for sevlet '" + getServletName()
123 + "'");
124
125 } else {
126 this.etagSupport = getDefaultETagSupport();
127
128 LOG.info("Use default ETag support configuration (value="
129 + this.etagSupport + ") for sevlet '" + getServletName()
130 + "'");
131 }
132
133 String hashSupport = getParameter(HASH_SUPPORT_PARAMETER);
134 if ("true".equalsIgnoreCase(hashSupport)) {
135 this.hashSupport = true;
136
137 LOG.info("Enable hash support for sevlet '" + getServletName()
138 + "'");
139
140 } else if ("false".equalsIgnoreCase(hashSupport)) {
141 this.hashSupport = false;
142
143 LOG.info("Disable hash support for sevlet '" + getServletName()
144 + "'");
145
146 } else {
147 this.hashSupport = getDefaultHashSupport();
148
149 LOG.info("Use default Hash support configuration (value="
150 + this.hashSupport + ") for sevlet '" + getServletName()
151 + "'");
152 }
153
154 String expires = getParameter(EXPIRE_PARAMETER);
155 if (expires != null) {
156 expirationDate = ExpirationDate.parse(getServletName(),
157 EXPIRE_PARAMETER, expires);
158 }
159
160 if (expirationDate == null
161 && NONE_EXPIRATION_KEYWORD.equalsIgnoreCase(expires) == false) {
162 expirationDate = ExpirationDate
163 .fromDelay(getDefaultExpirationDelay());
164 }
165
166 if (LOG.isInfoEnabled() && expirationDate != null) {
167 if (expirationDate.getExpiresDate() >= 0) {
168 LOG.info("Expire date setted to "
169 + expirationDate.getExpiresDate() + " for sevlet '"
170 + getServletName() + "'.");
171 }
172
173 if (expirationDate.getExpiresDelay() >= 0) {
174 LOG.info("Expire delay setted to "
175 + Delay.format(expirationDate.getExpiresDelay())
176 + " for sevlet '" + getServletName() + "'.");
177
178 }
179 }
180
181 String versionedExpires = getParameter(VERSIONED_EXPIRE_PARAMETER);
182 if (versionedExpires != null) {
183 versionedExpirationDate = ExpirationDate.parse(getServletName(),
184 VERSIONED_EXPIRE_PARAMETER, versionedExpires);
185 }
186
187 if (versionedExpirationDate == null
188 && NONE_EXPIRATION_KEYWORD.equalsIgnoreCase(versionedExpires) == false) {
189 versionedExpirationDate = ExpirationDate
190 .fromDelay(getDefaultVersionedExpirationDelay());
191 }
192
193 if (LOG.isInfoEnabled() && versionedExpirationDate != null) {
194 if (versionedExpirationDate.getExpiresDate() >= 0) {
195 LOG.info("Versioned resources expire date detected: "
196 + versionedExpirationDate.getExpiresDate()
197 + " for sevlet '" + getServletName() + "'");
198 }
199
200 if (versionedExpirationDate.getExpiresDelay() >= 0) {
201 LOG.info("Versioned resources expire delay setted to "
202 + Delay.format(versionedExpirationDate
203 .getExpiresDelay()) + " for sevlet '"
204 + getServletName() + "'");
205 }
206 }
207
208 if (hasLocaleSupport()) {
209 String localeSupportProperty = getParameter(LOCALE_SUPPORT_PARAMETER);
210 if ("false".equalsIgnoreCase(localeSupportProperty)) {
211 localeSupport = false;
212
213 LOG.info("LOCALE_SUPPORT is disabled for servlet '"
214 + getServletName() + "'.");
215 } else if ("true".equalsIgnoreCase(localeSupportProperty)) {
216 localeSupport = true;
217
218 LOG.info("LOCALE_SUPPORT is enabled for servlet '"
219 + getServletName() + "'.");
220 } else {
221 localeSupport = getDefaultLocaleSupport();
222
223 LOG.info("Use default value (" + localeSupport
224 + ") for LOCALE_SUPPORT for servlet '"
225 + getServletName() + "'.");
226 }
227
228 if (localeSupport) {
229 String acceptedLocaleNames = getParameter(FILTERED_LOCALES_PARAMETER);
230 if (acceptedLocaleNames != null
231 && acceptedLocaleNames.trim().length() > 0) {
232
233 StringTokenizer st = new StringTokenizer(
234 acceptedLocaleNames, ", ");
235 filtredLocales = new HashSet(st.countTokens());
236
237 for (; st.hasMoreTokens();) {
238 String localeName = st.nextToken();
239
240 Locale locale = convertLocaleName(localeName, false);
241 if (locale == null) {
242 LOG.error("Rejected locale '" + localeName + "'.");
243 continue;
244 }
245
246 filtredLocales.add(locale);
247 }
248
249 LOG.info("Accepted locale: " + filtredLocales
250 + " for servlet '" + getServletName() + "'.");
251 }
252
253 String localeName = getParameter(DEFAULT_LOCALE_PARAMETER);
254 if (localeName != null) {
255 defaultLocale = convertLocaleName(localeName, true);
256
257 if (defaultLocale != null) {
258 LOG.info("DEFAULT_LOCALE specify default locale to '"
259 + defaultLocale + "'.");
260 } else {
261 LOG.info("DEFAULT_LOCALE value '" + localeName
262 + "' is not valid !");
263 }
264 }
265 }
266 }
267 }
268
269 protected boolean hasLocaleSupport() {
270 return true;
271 }
272
273 private long getDefaultVersionedExpirationDelay() {
274 return Constants.DEFAULT_VERSIONED_EXPIRATION_DELAY;
275 }
276
277 protected boolean getDefaultLocaleSupport() {
278 return Constants.CLIENT_LOCALE_SUPPORT_DEFAULT_VALUE;
279 }
280
281 protected long getDefaultExpirationDelay() {
282 return Constants.DEFAULT_EXPIRATION_DELAY;
283 }
284
285 protected boolean getDefaultHashSupport() {
286 return Constants.HASH_SUPPORT;
287 }
288
289 protected boolean getDefaultETagSupport() {
290 return Constants.ETAG_SUPPORT;
291 }
292
293 protected boolean getDefaultGZipSupport() {
294 return Constants.GZIP_SUPPORT_DEFAULT_VALUE;
295 }
296
297 protected ExpirationDate getDefaultExpirationDate(boolean versioned) {
298 if (versioned && versionedExpirationDate != null) {
299 return versionedExpirationDate;
300 }
301
302 return expirationDate;
303 }
304
305 protected boolean hasEtagSupport() {
306 return etagSupport;
307 }
308
309 protected boolean hasHashSupport() {
310 return hashSupport;
311 }
312
313 protected final boolean hasGZipSupport() {
314 return gZipSupport;
315 }
316
317 protected final Locale getDefaultLocale(HttpServletRequest request,
318 HttpServletResponse response) {
319 synchronized (this) {
320 if (defaultLocale == null) {
321 defaultLocale = ServletTools.getDefaultLocale(
322 getServletContext(), request, response);
323 }
324 }
325
326 return defaultLocale;
327 }
328
329 protected final Locale convertLocaleName(String localeName, boolean accept) {
330 localeName = localeName.toLowerCase();
331
332 Locale locale;
333 synchronized (convertedLocales) {
334 locale = (Locale) convertedLocales.get(localeName);
335 }
336
337 if (locale != null) {
338 return locale;
339 }
340
341
342
343
344
345 StringTokenizer st = new StringTokenizer(localeName, "_");
346 String language = st.nextToken().toLowerCase();
347 String country = (st.hasMoreTokens()) ? st.nextToken().toLowerCase()
348 : "";
349 String variant = (st.hasMoreTokens()) ? st.nextToken().toLowerCase()
350 : "";
351
352 Locale bestLocale = null;
353 int bestHit = 0;
354
355 Locale locales[] = Locale.getAvailableLocales();
356 for (int i = 0; i < locales.length; i++) {
357 locale = locales[i];
358 if (accept && filtredLocales != null
359 && filtredLocales.contains(locale) == false) {
360 continue;
361 }
362
363 if (locale.getLanguage().equalsIgnoreCase(language) == false) {
364 continue;
365 }
366 int hit = 1;
367
368 String lcountry = locale.getCountry();
369 if (lcountry.equalsIgnoreCase(country)) {
370 hit += 2;
371
372 String lvariant = locale.getVariant();
373 if (lvariant.equalsIgnoreCase(variant)) {
374 hit += 2;
375
376 } else if (lvariant.length() < 1) {
377 hit++;
378 }
379
380 } else if (lcountry.length() < 1) {
381 hit++;
382 }
383
384 if (hit < bestHit) {
385 continue;
386 }
387
388 bestLocale = locale;
389 bestHit = hit;
390 }
391
392 if (bestLocale == null) {
393
394 return null;
395 }
396
397 synchronized (convertedLocales) {
398 convertedLocales.put(localeName, bestLocale);
399
400 return bestLocale;
401 }
402 }
403 }