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