Change build scripts
[jvcard.git] / src / be / nikiroo / jvcard / resources / bundles / TransBundle.java
1 package be.nikiroo.jvcard.resources.bundles;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.Writer;
6 import java.util.LinkedList;
7 import java.util.List;
8 import java.util.Locale;
9 import java.util.regex.Pattern;
10
11 import be.nikiroo.jvcard.resources.Bundles;
12 import be.nikiroo.jvcard.resources.Bundles.Bundle;
13 import be.nikiroo.jvcard.resources.Bundles.Target;
14 import be.nikiroo.jvcard.resources.ResourceList;
15 import be.nikiroo.jvcard.resources.enums.StringId;
16
17 /**
18 * This class manages the translation of {@link TransBundle.StringId}s into
19 * user-understandable text.
20 *
21 * @author niki
22 *
23 */
24 public class TransBundle extends Bundle<StringId> {
25 private boolean utf = true;
26 private Locale locale;
27 private boolean defaultLocale = false;
28
29 /**
30 * Create a translation service with the default language.
31 */
32 public TransBundle() {
33 new Bundles().super(StringId.class, Target.resources);
34 setLanguage(null);
35 }
36
37 /**
38 * Create a translation service for the given language. (Will fall back to
39 * the default one i not found.)
40 *
41 * @param language
42 * the language to use
43 */
44 public TransBundle(String language) {
45 new Bundles().super(StringId.class, Target.resources);
46
47 setLanguage(language);
48 }
49
50 /**
51 * Translate the given {@link StringId} into user text.
52 *
53 * @param stringId
54 * the ID to translate
55 * @param values
56 * the values to insert instead of the place holders in the
57 * translation
58 *
59 * @return the translated text with the given value where required
60 */
61 public String getString(StringId stringId, Object... values) {
62 StringId id = stringId;
63 String result = "";
64
65 if (!isUnicode()) {
66 try {
67 id = StringId.valueOf(stringId.name() + "_NOUTF");
68 } catch (IllegalArgumentException iae) {
69 // no special _NOUTF version found
70 }
71 }
72
73 if (id == StringId.NULL) {
74 result = "";
75 } else if (id == StringId.DUMMY) {
76 result = "[dummy]";
77 } else if (map.containsKey(id.name())) {
78 result = map.getString(id.name());
79 } else {
80 result = id.toString();
81 }
82
83 if (values != null && values.length > 0)
84 return String.format(locale, result, values);
85 else
86 return result;
87 }
88
89 /**
90 * Check if unicode characters should be used.
91 *
92 * @return TRUE to allow unicode
93 */
94 public boolean isUnicode() {
95 return utf;
96 }
97
98 /**
99 * Allow or disallow unicode characters in the program.
100 *
101 * @param utf
102 * TRUE to allow unuciode, FALSE to only allow ASCII characters
103 */
104 public void setUnicode(boolean utf) {
105 this.utf = utf;
106 }
107
108 /**
109 * Initialise the translation mappings for the given language.
110 *
111 * @param language
112 * the language to initialise, in the form "en-GB" or "fr" for
113 * instance
114 */
115 private void setLanguage(String language) {
116 defaultLocale = (language == null || language.length() == 0);
117 locale = getLocaleFor(language);
118 map = getBundle(Target.resources, locale);
119 }
120
121 @Override
122 public String getString(StringId id) {
123 return getString(id, (Object[]) null);
124 }
125
126 @Override
127 protected File getUpdateFile(String path) {
128 String code = locale.toString();
129 File file = null;
130 if (!defaultLocale && code.length() > 0) {
131 file = new File(path, name.name() + "_" + code + ".properties");
132 } else {
133 // Default properties file:
134 file = new File(path, name.name() + ".properties");
135 }
136
137 return file;
138 }
139
140 @Override
141 protected void writeHeader(Writer writer) throws IOException {
142 String code = locale.toString();
143 String name = locale.getDisplayCountry(locale);
144
145 if (name.length() == 0)
146 name = locale.getDisplayLanguage(locale);
147 if (name.length() == 0)
148 name = "default";
149
150 if (code.length() > 0) {
151 name = name + " (" + code + ")";
152 }
153
154 StringId.writeHeader(writer, name);
155 }
156
157 @Override
158 protected void writeValue(Writer writer, StringId id) throws IOException {
159 super.writeValue(writer, id);
160
161 String name = id.name() + "_NOUTF";
162 if (map.containsKey(name)) {
163 String value = map.getString(name).trim();
164 writeValue(writer, name, value);
165 }
166 }
167
168 /**
169 * Return the {@link Locale} representing the given language.
170 *
171 * @param language
172 * the language to initialise, in the form "en-GB" or "fr" for
173 * instance
174 *
175 * @return the corresponding {@link Locale} or the default {@link Locale} if
176 * it is not known
177 */
178 static private Locale getLocaleFor(String language) {
179 Locale locale;
180
181 if (language == null) {
182 locale = Locale.getDefault();
183 } else {
184 language = language.replaceAll("_", "-");
185 String lang = language;
186 String country = null;
187 if (language.contains("-")) {
188 lang = language.split("-")[0];
189 country = language.split("-")[1];
190 }
191
192 if (country != null)
193 locale = new Locale(lang, country);
194 else
195 locale = new Locale(lang);
196 }
197
198 return locale;
199 }
200
201 /**
202 * Return all the languages known by the program.
203 *
204 * @return the known language codes
205 */
206 static public List<String> getKnownLanguages() {
207 List<String> resources = new LinkedList<String>();
208
209 String regex = ".*" + Target.resources.name()
210 + "[_a-zA-Za]*\\.properties$";
211
212 for (String res : ResourceList.getResources(Pattern.compile(regex))) {
213 String resource = res;
214 int index = resource.lastIndexOf('/');
215 if (index >= 0 && index < (resource.length() - 1))
216 resource = resource.substring(index + 1);
217 if (resource.startsWith(Target.resources.name())) {
218 resource = resource.substring(0, resource.length()
219 - ".properties".length());
220 resource = resource.substring(Target.resources.name().length());
221 if (resource.startsWith("_")) {
222 resource = resource.substring(1);
223 resources.add(resource);
224 }
225 }
226 }
227
228 return resources;
229 }
230 }