001: // Copyright 2004, 2005 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.hivemind.util;
016:
017: import java.util.Locale;
018: import java.util.NoSuchElementException;
019:
020: import org.apache.hivemind.HiveMind;
021:
022: /**
023: * Used in a wide variety of resource searches. Generates
024: * a series of name variations from a base name, a
025: * {@link java.util.Locale} and an optional suffix.
026: *
027: * @author Howard Lewis Ship
028: */
029:
030: public class LocalizedNameGenerator {
031: private int _baseNameLength;
032: private String _suffix;
033: private StringBuffer _buffer;
034: private String _language;
035: private String _country;
036: private String _variant;
037: private int _state;
038: private int _prevState;
039:
040: private static final int INITIAL = 0;
041: private static final int LCV = 1;
042: private static final int LC = 2;
043: private static final int LV = 3;
044: private static final int L = 4;
045: private static final int BARE = 5;
046: private static final int EXHAUSTED = 6;
047:
048: public LocalizedNameGenerator(String baseName, Locale locale,
049: String suffix) {
050: _baseNameLength = baseName.length();
051:
052: if (locale != null) {
053: _language = locale.getLanguage();
054: _country = locale.getCountry();
055: _variant = locale.getVariant();
056: }
057:
058: _state = INITIAL;
059: _prevState = INITIAL;
060:
061: _suffix = suffix;
062:
063: _buffer = new StringBuffer(baseName);
064:
065: advance();
066: }
067:
068: private void advance() {
069: _prevState = _state;
070:
071: while (_state != EXHAUSTED) {
072: _state++;
073:
074: switch (_state) {
075: case LCV:
076:
077: if (HiveMind.isBlank(_variant))
078: continue;
079:
080: return;
081:
082: case LC:
083:
084: if (HiveMind.isBlank(_country))
085: continue;
086:
087: return;
088:
089: case LV:
090:
091: // If _country is null, then we've already generated this string
092: // as state LCV and we can continue directly to state L
093:
094: if (HiveMind.isBlank(_variant)
095: || HiveMind.isBlank(_country))
096: continue;
097:
098: return;
099:
100: case L:
101:
102: if (HiveMind.isBlank(_language))
103: continue;
104:
105: return;
106:
107: case BARE:
108: default:
109: return;
110: }
111: }
112: }
113:
114: /**
115: * Returns true if there are more name variants to be
116: * returned, false otherwise.
117: *
118: **/
119:
120: public boolean more() {
121: return _state != EXHAUSTED;
122: }
123:
124: /**
125: * Returns the next localized variant.
126: *
127: * @throws NoSuchElementException if all variants have been
128: * returned.
129: *
130: **/
131:
132: public String next() {
133: if (_state == EXHAUSTED)
134: throw new NoSuchElementException();
135:
136: String result = build();
137:
138: advance();
139:
140: return result;
141: }
142:
143: private String build() {
144: _buffer.setLength(_baseNameLength);
145:
146: if (_state == LC || _state == LCV || _state == L) {
147: _buffer.append('_');
148: _buffer.append(_language);
149: }
150:
151: // For LV, we want two underscores between language
152: // and variant.
153:
154: if (_state == LC || _state == LCV || _state == LV) {
155: _buffer.append('_');
156:
157: if (_state != LV)
158: _buffer.append(_country);
159: }
160:
161: if (_state == LV || _state == LCV) {
162: _buffer.append('_');
163: _buffer.append(_variant);
164: }
165:
166: if (_suffix != null)
167: _buffer.append(_suffix);
168:
169: return _buffer.toString();
170: }
171:
172: public Locale getCurrentLocale() {
173: switch (_prevState) {
174: case LCV:
175:
176: return new Locale(_language, _country, _variant);
177:
178: case LC:
179:
180: return new Locale(_language, _country, "");
181:
182: case LV:
183:
184: return new Locale(_language, "", _variant);
185:
186: case L:
187:
188: return new Locale(_language, "", "");
189:
190: default:
191: return null;
192: }
193: }
194: }
|