001
014
015 package com.liferay.portal.tools;
016
017 import com.liferay.portal.kernel.io.OutputStreamWriter;
018 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
019 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedWriter;
020 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
021 import com.liferay.portal.kernel.util.FileUtil;
022 import com.liferay.portal.kernel.util.GetterUtil;
023 import com.liferay.portal.kernel.util.PropertiesUtil;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.StringUtil;
026 import com.liferay.portal.kernel.util.Validator;
027 import com.liferay.portal.kernel.webcache.WebCacheItem;
028 import com.liferay.portal.util.InitUtil;
029 import com.liferay.portlet.translator.model.Translation;
030 import com.liferay.portlet.translator.util.TranslationWebCacheItem;
031
032 import java.io.File;
033 import java.io.FileInputStream;
034 import java.io.FileOutputStream;
035 import java.io.FileWriter;
036 import java.io.IOException;
037 import java.io.InputStream;
038
039 import java.util.Map;
040 import java.util.Properties;
041 import java.util.Set;
042 import java.util.TreeSet;
043
044
047 public class LangBuilder {
048
049 public static final String AUTOMATIC_COPY = " (Automatic Copy)";
050
051 public static final String AUTOMATIC_TRANSLATION =
052 " (Automatic Translation)";
053
054 public static void main(String[] args) {
055 Map<String, String> arguments = ArgumentsUtil.parseArguments(args);
056
057 System.setProperty("line.separator", StringPool.NEW_LINE);
058
059 InitUtil.initWithSpring();
060
061 String langDir = arguments.get("lang.dir");
062 String langFile = arguments.get("lang.file");
063 boolean langPlugin = GetterUtil.getBoolean(
064 arguments.get("lang.plugin"));
065 boolean langTranslate = GetterUtil.getBoolean(
066 arguments.get("lang.translate"), true);
067
068 try {
069 new LangBuilder(langDir, langFile, langPlugin, langTranslate);
070 }
071 catch (Exception e) {
072 e.printStackTrace();
073 }
074 }
075
076 public LangBuilder(
077 String langDir, String langFile, boolean langPlugin,
078 boolean langTranslate)
079 throws Exception {
080
081 _langDir = langDir;
082 _langFile = langFile;
083 _langTranslate = langTranslate;
084
085 if (langPlugin) {
086 _portalLanguageProperties = new Properties();
087
088 Class<?> clazz = getClass();
089
090 ClassLoader classLoader = clazz.getClassLoader();
091
092 InputStream is = classLoader.getResourceAsStream(
093 "content/Language.properties");
094
095 _portalLanguageProperties.load(is);
096 }
097
098 File renameKeysFile = new File(_langDir + "/rename.properties");
099
100 if (renameKeysFile.exists()) {
101 _renameKeys = PropertiesUtil.load(
102 FileUtil.read(renameKeysFile));
103 }
104
105 String content = _orderProperties(
106 new File(_langDir + "/" + _langFile + ".properties"));
107
108
109
110
111 _orderProperties(
112 new File(_langDir + "/" + _langFile + "_en_GB.properties"));
113
114 _createProperties(content, "ar");
115 _createProperties(content, "eu");
116 _createProperties(content, "bg");
117 _createProperties(content, "ca");
118 _createProperties(content, "zh_CN");
119 _createProperties(content, "zh_TW");
120 _createProperties(content, "hr");
121 _createProperties(content, "cs");
122 _createProperties(content, "nl");
123 _createProperties(content, "nl_BE", "nl");
124 _createProperties(content, "et");
125 _createProperties(content, "fi");
126 _createProperties(content, "fr");
127 _createProperties(content, "gl");
128 _createProperties(content, "de");
129 _createProperties(content, "el");
130 _createProperties(content, "iw");
131 _createProperties(content, "hi_IN");
132 _createProperties(content, "hu");
133 _createProperties(content, "in");
134 _createProperties(content, "it");
135 _createProperties(content, "ja");
136 _createProperties(content, "ko");
137 _createProperties(content, "nb");
138 _createProperties(content, "fa");
139 _createProperties(content, "pl");
140 _createProperties(content, "pt_BR");
141 _createProperties(content, "pt_PT", "pt_BR");
142 _createProperties(content, "ro");
143 _createProperties(content, "ru");
144 _createProperties(content, "sr_RS");
145 _createProperties(content, "sr_RS_latin");
146 _createProperties(content, "sk");
147 _createProperties(content, "sl");
148 _createProperties(content, "es");
149 _createProperties(content, "sv");
150 _createProperties(content, "tr");
151 _createProperties(content, "uk");
152 _createProperties(content, "vi");
153 }
154
155 private void _createProperties(String content, String languageId)
156 throws IOException {
157
158 _createProperties(content, languageId, null);
159 }
160
161 private void _createProperties(
162 String content, String languageId, String parentLanguageId)
163 throws IOException {
164
165 File propertiesFile = new File(
166 _langDir + "/" + _langFile + "_" + languageId + ".properties");
167
168 Properties properties = new Properties();
169
170 if (propertiesFile.exists()) {
171 properties = PropertiesUtil.load(
172 new FileInputStream(propertiesFile), StringPool.UTF8);
173 }
174
175 Properties parentProperties = null;
176
177 if (parentLanguageId != null) {
178 File parentPropertiesFile = new File(
179 _langDir + "/" + _langFile + "_" + parentLanguageId +
180 ".properties");
181
182 if (parentPropertiesFile.exists()) {
183 parentProperties = new Properties();
184
185 parentProperties = PropertiesUtil.load(
186 new FileInputStream(parentPropertiesFile), StringPool.UTF8);
187 }
188 }
189
190 String translationId = "en_" + languageId;
191
192 if (translationId.equals("en_pt_BR")) {
193 translationId = "en_pt";
194 }
195 else if (translationId.equals("en_pt_PT")) {
196 translationId = "en_pt";
197 }
198 else if (translationId.equals("en_zh_CN")) {
199 translationId = "en_zh";
200 }
201 else if (translationId.equals("en_zh_TW")) {
202 translationId = "en_zt";
203 }
204 else if (translationId.equals("en_hi_IN")) {
205 translationId = "en_hi";
206 }
207
208 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
209 new UnsyncStringReader(content));
210 UnsyncBufferedWriter unsyncBufferedWriter = new UnsyncBufferedWriter(
211 new OutputStreamWriter(
212 new FileOutputStream(propertiesFile), StringPool.UTF8));
213
214 int state = 0;
215
216 String line = null;
217
218 while ((line = unsyncBufferedReader.readLine()) != null) {
219 line = line.trim();
220
221 int pos = line.indexOf("=");
222
223 if (pos != -1) {
224 String key = line.substring(0, pos);
225 String value = line.substring(pos + 1, line.length());
226
227 if (((state == 1) && !key.startsWith("lang.")) ||
228 ((state == 2) && !key.startsWith("javax.portlet.")) ||
229 ((state == 3) && !key.startsWith("category.")) ||
230 ((state == 4) && !key.startsWith("model.resource.")) ||
231 ((state == 5) && !key.startsWith("action.")) ||
232 ((state == 7) && !key.startsWith("currency.")) ||
233 ((state != 7) && key.startsWith("currency."))) {
234
235 throw new RuntimeException(
236 "File " + languageId + " with state " + state +
237 " has key " + key);
238 }
239
240 String translatedText = properties.getProperty(key);
241
242 if ((translatedText == null) && (parentProperties != null)) {
243 translatedText = parentProperties.getProperty(key);
244 }
245
246 if ((translatedText == null) && (_renameKeys != null)) {
247 String renameKey = _renameKeys.getProperty(key);
248
249 if (renameKey != null) {
250 translatedText = properties.getProperty(key);
251
252 if ((translatedText == null) &&
253 (parentProperties != null)) {
254
255 translatedText = parentProperties.getProperty(key);
256 }
257 }
258 }
259
260 if ((translatedText != null) &&
261 ((translatedText.indexOf("Babel Fish") != -1) ||
262 (translatedText.indexOf("Yahoo! - 999") != -1))) {
263
264 translatedText = "";
265 }
266
267 if ((translatedText == null) || translatedText.equals("")) {
268 if (line.indexOf("{") != -1 || line.indexOf("<") != -1) {
269 translatedText = value + AUTOMATIC_COPY;
270 }
271 else if (line.indexOf("[") != -1) {
272 pos = line.indexOf("[");
273
274 String baseKey = line.substring(0, pos);
275
276 translatedText =
277 properties.getProperty(baseKey) + AUTOMATIC_COPY;
278 }
279 else if (key.equals("lang.dir")) {
280 translatedText = "ltr";
281 }
282 else if (key.equals("lang.line.begin")) {
283 translatedText = "left";
284 }
285 else if (key.equals("lang.line.end")) {
286 translatedText = "right";
287 }
288 else if (translationId.equals("en_el") &&
289 (key.equals("enabled") || key.equals("on") ||
290 key.equals("on-date"))) {
291
292 translatedText = "";
293 }
294 else if (translationId.equals("en_es") &&
295 key.equals("am")) {
296
297 translatedText = "";
298 }
299 else if (translationId.equals("en_it") &&
300 key.equals("am")) {
301
302 translatedText = "";
303 }
304 else if (translationId.equals("en_ja") &&
305 (key.equals("any") || key.equals("anytime") ||
306 key.equals("down") || key.equals("on") ||
307 key.equals("on-date") || key.equals("the"))) {
308
309 translatedText = "";
310 }
311 else if (translationId.equals("en_ko") &&
312 key.equals("the")) {
313
314 translatedText = "";
315 }
316 else {
317 translatedText = _translate(
318 translationId, key, value, 0);
319
320 if (Validator.isNull(translatedText)) {
321 translatedText = value + AUTOMATIC_COPY;
322 }
323 else {
324 translatedText =
325 translatedText + AUTOMATIC_TRANSLATION;
326 }
327 }
328 }
329
330 if (Validator.isNotNull(translatedText)) {
331 if ((translatedText.indexOf("Babel Fish") != -1) ||
332 (translatedText.indexOf("Yahoo! - 999") != -1)) {
333
334 throw new IOException(
335 "IP was blocked because of over usage. Please " +
336 "use another IP.");
337 }
338
339 if (translatedText.indexOf("'") != -1) {
340 translatedText = StringUtil.replace(
341 translatedText, "'", "\'");
342 }
343
344 translatedText = StringUtil.replace(
345 translatedText.trim(),
346 new String[] {
347 " ", "<b>", "</b>", "<i>", "</i>"
348 },
349 new String[] {
350 " ", "<strong>", "</strong>", "<em>", "</em>"
351 });
352
353 unsyncBufferedWriter.write(key + "=" + translatedText);
354
355 unsyncBufferedWriter.newLine();
356 unsyncBufferedWriter.flush();
357 }
358 }
359 else {
360 if (line.startsWith("## Language settings")) {
361 if (state == 1) {
362 throw new RuntimeException(languageId);
363 }
364
365 state = 1;
366 }
367 else if (line.startsWith(
368 "## Portlet descriptions and titles")) {
369
370 if (state == 2) {
371 throw new RuntimeException(languageId);
372 }
373
374 state = 2;
375 }
376 else if (line.startsWith("## Category titles")) {
377 if (state == 3) {
378 throw new RuntimeException(languageId);
379 }
380
381 state = 3;
382 }
383 else if (line.startsWith("## Model resources")) {
384 if (state == 4) {
385 throw new RuntimeException(languageId);
386 }
387
388 state = 4;
389 }
390 else if (line.startsWith("## Action names")) {
391 if (state == 5) {
392 throw new RuntimeException(languageId);
393 }
394
395 state = 5;
396 }
397 else if (line.startsWith("## Messages")) {
398 if (state == 6) {
399 throw new RuntimeException(languageId);
400 }
401
402 state = 6;
403 }
404 else if (line.startsWith("## Currency")) {
405 if (state == 7) {
406 throw new RuntimeException(languageId);
407 }
408
409 state = 7;
410 }
411
412 unsyncBufferedWriter.write(line);
413
414 unsyncBufferedWriter.newLine();
415 unsyncBufferedWriter.flush();
416 }
417 }
418
419 unsyncBufferedReader.close();
420 unsyncBufferedWriter.close();
421 }
422
423 private String _orderProperties(File propertiesFile) throws IOException {
424 if (!propertiesFile.exists()) {
425 return null;
426 }
427
428 String content = FileUtil.read(propertiesFile);
429
430 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
431 new UnsyncStringReader(content));
432 UnsyncBufferedWriter unsyncBufferedWriter = new UnsyncBufferedWriter(
433 new FileWriter(propertiesFile));
434
435 Set<String> messages = new TreeSet<String>();
436
437 boolean begin = false;
438
439 String line = null;
440
441 while ((line = unsyncBufferedReader.readLine()) != null) {
442 int pos = line.indexOf("=");
443
444 if (pos != -1) {
445 String key = line.substring(0, pos);
446 String value = line.substring(pos + 1, line.length());
447
448 if (_portalLanguageProperties != null) {
449 String portalValue = String.valueOf(
450 _portalLanguageProperties.get(key));
451
452 if (value.equals(portalValue)) {
453 System.out.println("Duplicate key " + key);
454 }
455 }
456
457 messages.add(key + "=" + value);
458 }
459 else {
460 if (begin == true && line.equals("")) {
461 _sortAndWrite(unsyncBufferedWriter, messages);
462 }
463
464 if (line.equals("")) {
465 begin = !begin;
466 }
467
468 unsyncBufferedWriter.write(line);
469 unsyncBufferedWriter.newLine();
470 }
471
472 unsyncBufferedWriter.flush();
473 }
474
475 if (messages.size() > 0) {
476 _sortAndWrite(unsyncBufferedWriter, messages);
477 }
478
479 unsyncBufferedReader.close();
480 unsyncBufferedWriter.close();
481
482 return FileUtil.read(propertiesFile);
483 }
484
485 private void _sortAndWrite(
486 UnsyncBufferedWriter unsyncBufferedWriter, Set<String> messages)
487 throws IOException {
488
489 String[] messagesArray = messages.toArray(new String[messages.size()]);
490
491 for (int i = 0; i < messagesArray.length; i++) {
492 unsyncBufferedWriter.write(messagesArray[i]);
493 unsyncBufferedWriter.newLine();
494 }
495
496 messages.clear();
497 }
498
499 private String _translate(
500 String translationId, String key, String fromText, int limit) {
501
502 if (translationId.equals("en_ar") ||
503 translationId.equals("en_eu") ||
504 translationId.equals("en_bg") ||
505 translationId.equals("en_ca") ||
506 translationId.equals("en_hr") ||
507 translationId.equals("en_cs") ||
508 translationId.equals("en_fi") ||
509 translationId.equals("en_gl") ||
510 translationId.equals("en_iw") ||
511 translationId.equals("en_hi") ||
512 translationId.equals("en_hu") ||
513 translationId.equals("en_in") ||
514 translationId.equals("en_nb") ||
515 translationId.equals("en_fa") ||
516 translationId.equals("en_pl") ||
517 translationId.equals("en_ro") ||
518 translationId.equals("en_ru") ||
519 translationId.equals("en_sr_RS") ||
520 translationId.equals("en_sr_RS_latin") ||
521 translationId.equals("en_sk") ||
522 translationId.equals("en_sl") ||
523 translationId.equals("en_sv") ||
524 translationId.equals("en_tr") ||
525 translationId.equals("en_uk") ||
526 translationId.equals("en_vi") ||
527 translationId.equals("en_et")) {
528
529
530
531
532
533
534
535 return null;
536 }
537
538 if (!_langTranslate) {
539 return null;
540 }
541
542
543
544 if (limit == 3) {
545 return null;
546 }
547
548 String toText = null;
549
550 try {
551 System.out.println(
552 "Translating " + translationId + " " + key + " " + fromText);
553
554 WebCacheItem wci = new TranslationWebCacheItem(
555 translationId, fromText);
556
557 Translation translation = (Translation)wci.convert("");
558
559 toText = translation.getToText();
560
561 if ((toText != null) &&
562 (toText.indexOf("Babel Fish") != -1)) {
563
564 toText = null;
565 }
566 }
567 catch (Exception e) {
568 e.printStackTrace();
569 }
570
571
572
573 if (toText == null) {
574 return _translate(translationId, key, fromText, ++limit);
575 }
576
577 return toText;
578 }
579
580 private String _langDir;
581 private String _langFile;
582 private boolean _langTranslate;
583 private Properties _portalLanguageProperties;
584 private Properties _renameKeys;
585
586 }