001: // Copyright 2006, 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.internal.services;
016:
017: import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newConcurrentMap;
018: import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
019:
020: import java.util.Locale;
021: import java.util.Map;
022: import java.util.Set;
023:
024: import org.apache.tapestry.ioc.annotations.Inject;
025: import org.apache.tapestry.ioc.annotations.Symbol;
026: import org.apache.tapestry.ioc.services.ThreadLocale;
027: import org.apache.tapestry.services.PersistentLocale;
028:
029: /**
030: * Given a set of supported locales, for a specified desired locale, sets the current thread's
031: * locale to a supported locale that is closest to the desired.
032: */
033: public class LocalizationSetterImpl implements LocalizationSetter {
034: private final ThreadLocale _threadLocale;
035:
036: private final Locale _defaultLocale;
037:
038: private final Set<String> _acceptedLocaleNames;
039:
040: private final Map<String, Locale> _localeCache = newConcurrentMap();
041:
042: private final PersistentLocale _persistentLocale;
043:
044: public LocalizationSetterImpl(PersistentLocale persistentLocale,
045: ThreadLocale threadLocale, @Inject
046: @Symbol("tapestry.supported-locales")
047: String acceptedLocaleNames) {
048: _persistentLocale = persistentLocale;
049:
050: _threadLocale = threadLocale;
051:
052: String[] names = acceptedLocaleNames.split(",");
053:
054: _defaultLocale = toLocale(names[0]);
055:
056: _acceptedLocaleNames = newSet(names);
057: }
058:
059: Locale toLocale(String localeName) {
060: Locale result = _localeCache.get(localeName);
061:
062: if (result == null) {
063: result = constructLocale(localeName);
064: _localeCache.put(localeName, result);
065: }
066:
067: return result;
068: }
069:
070: private Locale constructLocale(String name) {
071: String[] terms = name.split("_");
072:
073: switch (terms.length) {
074: case 1:
075: return new Locale(terms[0], "");
076:
077: case 2:
078: return new Locale(terms[0], terms[1]);
079:
080: case 3:
081:
082: return new Locale(terms[0], terms[1], terms[2]);
083:
084: default:
085:
086: throw new IllegalArgumentException();
087: }
088: }
089:
090: public void setThreadLocale(Locale desiredLocale) {
091: if (_persistentLocale.get() != null)
092: desiredLocale = _persistentLocale.get();
093:
094: Locale locale = findClosestAcceptedLocale(desiredLocale);
095:
096: _threadLocale.setLocale(locale);
097: }
098:
099: private Locale findClosestAcceptedLocale(Locale desiredLocale) {
100: String localeName = desiredLocale.toString();
101:
102: while (true) {
103: if (_acceptedLocaleNames.contains(localeName))
104: return toLocale(localeName);
105:
106: localeName = stripTerm(localeName);
107:
108: if (localeName.length() == 0)
109: break;
110: }
111:
112: return _defaultLocale;
113: }
114:
115: static String stripTerm(String localeName) {
116: int scorex = localeName.lastIndexOf('_');
117:
118: return scorex < 0 ? "" : localeName.substring(0, scorex);
119: }
120:
121: }
|