1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.tools;
16  
17  import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
18  import com.liferay.portal.kernel.io.unsync.UnsyncBufferedWriter;
19  import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
20  import com.liferay.portal.kernel.util.FileUtil;
21  import com.liferay.portal.kernel.util.PropertiesUtil;
22  import com.liferay.portal.kernel.util.StringUtil;
23  import com.liferay.portal.kernel.util.Validator;
24  import com.liferay.portal.kernel.webcache.WebCacheItem;
25  import com.liferay.portal.util.InitUtil;
26  import com.liferay.portlet.translator.model.Translation;
27  import com.liferay.portlet.translator.util.TranslationWebCacheItem;
28  
29  import java.io.File;
30  import java.io.FileInputStream;
31  import java.io.FileWriter;
32  import java.io.IOException;
33  
34  import java.util.Properties;
35  import java.util.Set;
36  import java.util.TreeSet;
37  
38  /**
39   * <a href="LangBuilder.java.html"><b><i>View Source</i></b></a>
40   *
41   * @author Brian Wing Shun Chan
42   */
43  public class LangBuilder {
44  
45      public static void main(String[] args) {
46          InitUtil.initWithSpring();
47  
48          if (args.length == 2) {
49              new LangBuilder(args[0], args[1], null);
50          }
51          else if (args.length == 3) {
52              new LangBuilder(args[0], args[1], args[2]);
53          }
54          else {
55              throw new IllegalArgumentException();
56          }
57      }
58  
59      public LangBuilder(String langDir, String langFile, String langCode) {
60          try {
61              _langDir = langDir;
62              _langFile = langFile;
63  
64              File renameKeysFile = new File(_langDir + "/rename.properties");
65  
66              if (renameKeysFile.exists()) {
67                  _renameKeys = PropertiesUtil.load(
68                      FileUtil.read(renameKeysFile));
69              }
70  
71              String content = _orderProps(
72                  new File(_langDir + "/" + _langFile + ".properties"));
73  
74              if (Validator.isNotNull(langCode) && !langCode.startsWith("$")) {
75                  _createProps(content, langCode);
76              }
77              else {
78                  _createProps(content, "ar"); // Arabic
79                  _createProps(content, "eu"); // Basque
80                  _createProps(content, "bg"); // Bulgarian
81                  _createProps(content, "ca"); // Catalan
82                  _createProps(content, "zh_CN"); // Chinese (China)
83                  _createProps(content, "zh_TW"); // Chinese (Taiwan)
84                  _createProps(content, "cs"); // Czech
85                  _createProps(content, "nl"); // Dutch
86                  _createProps(content, "et"); // Estonian
87                  _createProps(content, "fi"); // Finnish
88                  _createProps(content, "fr"); // French
89                  _createProps(content, "gl"); // Galician
90                  _createProps(content, "de"); // German
91                  _createProps(content, "el"); // Greek
92                  _createProps(content, "iw"); // Hebrew
93                  _createProps(content, "hi_IN"); // Hindi (India)
94                  _createProps(content, "hu"); // Hungarian
95                  _createProps(content, "it"); // Italian
96                  _createProps(content, "ja"); // Japanese
97                  _createProps(content, "ko"); // Korean
98                  _createProps(content, "nb"); // Norwegian Bokmål
99                  _createProps(content, "fa"); // Persian
100                 _createProps(content, "pl"); // Polish
101                 _createProps(content, "pt_BR"); // Portuguese (Brazil)
102                 _createProps(content, "pt_PT"); // Portuguese (Portugal)
103                 _createProps(content, "ru"); // Russian
104                 _createProps(content, "sk"); // Slovak
105                 _createProps(content, "es"); // Spanish
106                 _createProps(content, "sv"); // Swedish
107                 _createProps(content, "tr"); // Turkish
108                 _createProps(content, "uk"); // Ukrainian
109                 _createProps(content, "vi"); // Vietnamese
110             }
111         }
112         catch (Exception e) {
113             e.printStackTrace();
114         }
115     }
116 
117     private void _createProps(String content, String languageId)
118         throws IOException {
119 
120         File propsFile = new File(
121             _langDir + "/" + _langFile + "_" + languageId + ".properties");
122 
123         Properties props = new Properties();
124 
125         if (propsFile.exists()) {
126             props.load(new FileInputStream(propsFile));
127         }
128 
129         File nativePropsFile = new File(
130             _langDir + "/" + _langFile + "_" + languageId +
131                 ".properties.native");
132 
133         Properties nativeProps = new Properties();
134 
135         if (nativePropsFile.exists()) {
136             nativeProps.load(new FileInputStream(nativePropsFile));
137         }
138 
139         String translationId = "en_" + languageId;
140 
141         if (translationId.equals("en_pt_BR")) {
142             translationId = "en_pt";
143         }
144         else if (translationId.equals("en_pt_PT")) {
145             translationId = "en_pt";
146         }
147         else if (translationId.equals("en_zh_CN")) {
148             translationId = "en_zh";
149         }
150         else if (translationId.equals("en_zh_TW")) {
151             translationId = "en_zt";
152         }
153         else if (translationId.equals("en_hi_IN")) {
154             translationId = "en_hi";
155         }
156 
157         UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
158             new UnsyncStringReader(content));
159         UnsyncBufferedWriter unsyncBufferedWriter = new UnsyncBufferedWriter(
160             new FileWriter(nativePropsFile));
161 
162         String line = null;
163 
164         while ((line = unsyncBufferedReader.readLine()) != null) {
165             line = line.trim();
166 
167             int pos = line.indexOf("=");
168 
169             if (pos != -1) {
170                 String key = line.substring(0, pos);
171                 String value = line.substring(pos + 1, line.length());
172 
173                 String nativeValue = nativeProps.getProperty(key);
174                 String translatedText = props.getProperty(key);
175 
176                 if ((nativeValue == null) && (translatedText == null) &&
177                     (_renameKeys != null)) {
178 
179                     String renameKey = _renameKeys.getProperty(key);
180 
181                     if (renameKey != null) {
182                         nativeValue = nativeProps.getProperty(renameKey);
183                         translatedText = props.getProperty(renameKey);
184                     }
185                 }
186 
187                 if ((translatedText != null) &&
188                     ((translatedText.indexOf("Babel Fish") != -1) ||
189                      (translatedText.indexOf("Yahoo! - 999") != -1))) {
190 
191                     translatedText = "";
192                 }
193                 else if ((nativeValue != null) &&
194                          (nativeValue.endsWith(_AUTOMATIC_TRANSLATION))) {
195 
196                     translatedText += _AUTOMATIC_TRANSLATION;
197                 }
198 
199                 if ((translatedText == null) || translatedText.equals("")) {
200                     if (line.indexOf("{") != -1 || line.indexOf("<") != -1) {
201                         translatedText = value + _AUTOMATIC_COPY;
202                     }
203                     else if (line.indexOf("[") != -1) {
204                         pos = line.indexOf("[");
205 
206                         String baseKey = line.substring(0, pos);
207 
208                         translatedText =
209                             props.getProperty(baseKey) + _AUTOMATIC_COPY;
210                     }
211                     else if (key.equals("lang.dir")) {
212                         translatedText = "ltr";
213                     }
214                     else if (key.equals("lang.line.begin")) {
215                         translatedText = "left";
216                     }
217                     else if (key.equals("lang.line.end")) {
218                         translatedText = "right";
219                     }
220                     else if (translationId.equals("en_el") &&
221                              (key.equals("enabled") || key.equals("on") ||
222                               key.equals("on-date"))) {
223 
224                         translatedText = "";
225                     }
226                     else if (translationId.equals("en_es") &&
227                              key.equals("am")) {
228 
229                         translatedText = "";
230                     }
231                     else if (translationId.equals("en_it") &&
232                              key.equals("am")) {
233 
234                         translatedText = "";
235                     }
236                     else if (translationId.equals("en_ja") &&
237                              (key.equals("any") || key.equals("anytime") ||
238                               key.equals("down") || key.equals("on") ||
239                               key.equals("on-date") || key.equals("the"))) {
240 
241                         translatedText = "";
242                     }
243                     else if (translationId.equals("en_ko") &&
244                              key.equals("the")) {
245 
246                         translatedText = "";
247                     }
248                     else {
249                         translatedText = _translate(
250                             translationId, key, value, 0);
251 
252                         if (Validator.isNull(translatedText)) {
253                             translatedText = value + _AUTOMATIC_COPY;
254                         }
255                     }
256                 }
257 
258                 if (Validator.isNotNull(translatedText)) {
259                     if ((translatedText.indexOf("Babel Fish") != -1) ||
260                         (translatedText.indexOf("Yahoo! - 999") != -1)) {
261 
262                         throw new IOException(
263                             "IP was blocked because of over usage. Please " +
264                                 "use another IP.");
265                     }
266 
267                     if (translatedText.indexOf("&#39;") != -1) {
268                         translatedText = StringUtil.replace(
269                             translatedText, "&#39;", "\'");
270                     }
271 
272                     unsyncBufferedWriter.write(key + "=" + translatedText);
273 
274                     unsyncBufferedWriter.newLine();
275                     unsyncBufferedWriter.flush();
276                 }
277                 else if (nativeProps.containsKey(key)) {
278                     unsyncBufferedWriter.write(key + "=");
279 
280                     unsyncBufferedWriter.newLine();
281                     unsyncBufferedWriter.flush();
282                 }
283             }
284             else {
285                 unsyncBufferedWriter.write(line);
286 
287                 unsyncBufferedWriter.newLine();
288                 unsyncBufferedWriter.flush();
289             }
290         }
291 
292         unsyncBufferedReader.close();
293         unsyncBufferedWriter.close();
294     }
295 
296     private String _orderProps(File propsFile) throws IOException {
297         String content = FileUtil.read(propsFile);
298 
299         UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
300             new UnsyncStringReader(content));
301         UnsyncBufferedWriter unsyncBufferedWriter = new UnsyncBufferedWriter(
302             new FileWriter(propsFile));
303 
304         Set<String> messages = new TreeSet<String>();
305 
306         boolean begin = false;
307 
308         String line = null;
309 
310         while ((line = unsyncBufferedReader.readLine()) != null) {
311             int pos = line.indexOf("=");
312 
313             if (pos != -1) {
314                 String key = line.substring(0, pos);
315                 String value = line.substring(pos + 1, line.length());
316 
317                 messages.add(key + "=" + value);
318             }
319             else {
320                 if (begin == true && line.equals("")) {
321                     _sortAndWrite(unsyncBufferedWriter, messages);
322                 }
323 
324                 if (line.equals("")) {
325                     begin = !begin;
326                 }
327 
328                 unsyncBufferedWriter.write(line);
329                 unsyncBufferedWriter.newLine();
330             }
331 
332             unsyncBufferedWriter.flush();
333         }
334 
335         if (messages.size() > 0) {
336             _sortAndWrite(unsyncBufferedWriter, messages);
337         }
338 
339         unsyncBufferedReader.close();
340         unsyncBufferedWriter.close();
341 
342         return FileUtil.read(propsFile);
343     }
344 
345     private void _sortAndWrite(
346             UnsyncBufferedWriter unsyncBufferedWriter, Set<String> messages)
347         throws IOException {
348 
349         String[] messagesArray = messages.toArray(new String[messages.size()]);
350 
351         for (int i = 0; i < messagesArray.length; i++) {
352             unsyncBufferedWriter.write(messagesArray[i]);
353             unsyncBufferedWriter.newLine();
354         }
355 
356         messages.clear();
357     }
358 
359     private String _translate(
360         String translationId, String key, String fromText, int limit) {
361 
362         if (translationId.equals("en_ar") ||
363             translationId.equals("en_eu") ||
364             translationId.equals("en_bg") ||
365             translationId.equals("en_ca") ||
366             translationId.equals("en_cs") ||
367             translationId.equals("en_fi") ||
368             translationId.equals("en_gl") ||
369             translationId.equals("en_iw") ||
370             translationId.equals("en_hi") ||
371             translationId.equals("en_hu") ||
372             translationId.equals("en_nb") ||
373             translationId.equals("en_fa") ||
374             translationId.equals("en_pl") ||
375             translationId.equals("en_ru") ||
376             translationId.equals("en_sk") ||
377             translationId.equals("en_sv") ||
378             translationId.equals("en_tr") ||
379             translationId.equals("en_uk") ||
380             translationId.equals("en_vi") ||
381             translationId.equals("en_et")) {
382 
383             // Automatic translator does not support Arabic, Basque, Bulgarian,
384             // Catalan, Czech, Finnish, Galician, Hebrew, Hindi, Hungarian,
385             // Norwegian Bokmål,Persian, Polish, Russian, Slovak, Swedish,
386             // Turkish, Ukrainian, or Vietnamese
387 
388             return null;
389         }
390 
391         // Limit the number of retries to 3
392 
393         if (limit == 3) {
394             return null;
395         }
396 
397         String toText = null;
398 
399         try {
400             System.out.println(
401                 "Translating " + translationId + " " + key + " " + fromText);
402 
403             WebCacheItem wci = new TranslationWebCacheItem(
404                 translationId, fromText);
405 
406             Translation translation = (Translation)wci.convert("");
407 
408             toText = translation.getToText();
409 
410             if ((toText != null) &&
411                 (toText.indexOf("Babel Fish") != -1)) {
412 
413                 toText = null;
414             }
415         }
416         catch (Exception e) {
417             e.printStackTrace();
418         }
419 
420         // Keep trying
421 
422         if (toText == null) {
423             return _translate(translationId, key, fromText, ++limit);
424         }
425 
426         if (Validator.isNotNull(toText)) {
427             toText += _AUTOMATIC_TRANSLATION;
428         }
429 
430         return toText;
431     }
432 
433     private static final String _AUTOMATIC_COPY = " (Automatic Copy)";
434 
435     private static final String _AUTOMATIC_TRANSLATION =
436         " (Automatic Translation)";
437 
438     private String _langDir;
439     private String _langFile;
440     private Properties _renameKeys;
441 
442 }