001: /*
002: * Copyright 2003 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package velosurf.web.l10n;
018:
019: import org.apache.velocity.tools.view.context.ViewContext;
020:
021: import javax.servlet.http.HttpServletRequest;
022: import javax.servlet.http.HttpSession;
023: import java.util.*;
024: import java.text.MessageFormat;
025: import java.lang.ref.WeakReference;
026:
027: import velosurf.util.Logger;
028:
029: /** <p>This class rely on the "Accepted-Language" HTTP header to detect
030: * the appropriate locale to be used.</p>
031: *
032: * <p>This tool accepts a "default-locale" configuration parameter in toolbox.xml.</p>
033: * <p>It is meant for the session scope.</p>
034: *
035: * @author <a href=mailto:claude.brisson@gmail.com>Claude Brisson</a>
036: *
037: **/
038:
039: public abstract class HTTPLocalizerTool implements Localizer {
040:
041: /**
042: * Initialize this tool.
043: * @param initData a view context
044: */
045: public void init(Object initData) {
046: if (initData instanceof ViewContext) {
047: HttpSession session = ((ViewContext) initData).getRequest()
048: .getSession();
049: if (session != null) {
050: this .session = new WeakReference<HttpSession>(session);
051: Locale locale = (Locale) session
052: .getAttribute("velosurf.l10n.active-locale");
053: if (locale == null) {
054: /* means the localization filter did not intercept this query */
055: locale = getBestLocale(listFromEnum(((ViewContext) initData)
056: .getRequest().getLocales()));
057: Logger
058: .trace("l10n: unlocalized page - using locale "
059: + locale);
060: }
061: setLocale(locale);
062: }
063: } else {
064: Logger
065: .error("l10n: Localizer tool should be used in a session scope!");
066: return;
067: }
068: }
069:
070: /**
071: * Transform an enumeration into a list of locales.
072: * @param e enumeration
073: * @return a list of locales
074: */
075: private static List<Locale> listFromEnum(Enumeration e) {
076: List<Locale> list = new ArrayList<Locale>();
077: while (e.hasMoreElements()) {
078: list.add((Locale) e.nextElement());
079: }
080: return list;
081: }
082:
083: /**
084: * Get the locale best matching available localized data among a list.
085: * @param locales list of input locales
086: * @return best matching locale
087: */
088: public Locale getBestLocale(List<Locale> locales) {
089: for (Locale locale : locales) {
090: if (hasLocale(locale)) {
091: return locale;
092: }
093: }
094: /* second pass without the country code */
095: for (Locale locale : locales) {
096: String country = locale.getCountry();
097: if (country != null && country.length() > 0) {
098: Locale l = new Locale(locale.getLanguage());
099: if (hasLocale(l)) {
100: return l;
101: }
102: }
103: }
104: return null;
105: }
106:
107: /**
108: * Check for the presence of a locale.
109: * @param locale locale to check
110: * @return true if present
111: */
112: public abstract boolean hasLocale(Locale locale);
113:
114: /**
115: * Current locale setter.
116: * @param locale locale
117: */
118: public void setLocale(Locale locale) {
119: this .locale = locale;
120: }
121:
122: /** Current lcoale getter.
123: *
124: * @return current locale
125: */
126: public Locale getLocale() {
127: checkLocaleChange();
128: return locale;
129: }
130:
131: /**
132: * Check that the locale has not changed in the session.
133: */
134: public void checkLocaleChange() {
135: HttpSession s = session.get();
136: if (s != null) {
137: Locale l = (Locale) s
138: .getAttribute("velosurf.l10n.active-locale");
139: if (l != null && !l.equals(locale)) {
140: setLocale(l);
141: }
142: }
143: }
144:
145: /**
146: * Get the localized message for this key.
147: * @param id message key
148: * @return localized message (or id if not found).
149: */
150: public abstract String get(Object id);
151:
152: /**
153: * Get the localized parameterized message for this key.
154: * @param id message key
155: * @param params message parameters
156: * @return localized message (or id if not found).
157: */
158: public String get(Object id, Object... params) {
159: String message = get(id).replaceAll("'", "''");
160: return MessageFormat.format(message, params);
161: }
162:
163: /** keep a reference on the session */
164: private WeakReference<HttpSession> session = null;
165:
166: /** current locale */
167: protected Locale locale = null;
168: }
|