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, "hi_IN"); // Hindi (India)
93                  _createProps(content, "hu"); // Hungarian
94                  _createProps(content, "it"); // Italian
95                  _createProps(content, "ja"); // Japanese
96                  _createProps(content, "ko"); // Korean
97                  _createProps(content, "nb"); // Norwegian Bokmål
98                  _createProps(content, "fa"); // Persian
99                  _createProps(content, "pl"); // Polish
100                 _createProps(content, "pt_BR"); // Portuguese (Brazil)
101                 _createProps(content, "pt_PT"); // Portuguese (Portugal)
102                 _createProps(content, "ru"); // Russian
103                 _createProps(content, "sk"); // Slovak
104                 _createProps(content, "es"); // Spanish
105                 _createProps(content, "sv"); // Swedish
106                 _createProps(content, "tr"); // Turkish
107                 _createProps(content, "vi"); // Vietnamese
108             }
109         }
110         catch (Exception e) {
111             e.printStackTrace();
112         }
113     }
114 
115     private void _createProps(String content, String languageId)
116         throws IOException {
117 
118         File propsFile = new File(
119             _langDir + "/" + _langFile + "_" + languageId + ".properties");
120 
121         Properties props = new Properties();
122 
123         if (propsFile.exists()) {
124             props.load(new FileInputStream(propsFile));
125         }
126 
127         File nativePropsFile = new File(
128             _langDir + "/" + _langFile + "_" + languageId +
129                 ".properties.native");
130 
131         Properties nativeProps = new Properties();
132 
133         if (nativePropsFile.exists()) {
134             nativeProps.load(new FileInputStream(nativePropsFile));
135         }
136 
137         String translationId = "en_" + languageId;
138 
139         if (translationId.equals("en_pt_BR")) {
140             translationId = "en_pt";
141         }
142         else if (translationId.equals("en_pt_PT")) {
143             translationId = "en_pt";
144         }
145         else if (translationId.equals("en_zh_CN")) {
146             translationId = "en_zh";
147         }
148         else if (translationId.equals("en_zh_TW")) {
149             translationId = "en_zt";
150         }
151         else if (translationId.equals("en_hi_IN")) {
152             translationId = "en_hi";
153         }
154 
155         UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
156             new UnsyncStringReader(content));
157         UnsyncBufferedWriter unsyncBufferedWriter = new UnsyncBufferedWriter(
158             new FileWriter(nativePropsFile));
159 
160         String line = null;
161 
162         while ((line = unsyncBufferedReader.readLine()) != null) {
163             line = line.trim();
164 
165             int pos = line.indexOf("=");
166 
167             if (pos != -1) {
168                 String key = line.substring(0, pos);
169                 String value = line.substring(pos + 1, line.length());
170 
171                 String nativeValue = nativeProps.getProperty(key);
172                 String translatedText = props.getProperty(key);
173 
174                 if ((nativeValue == null) && (translatedText == null) &&
175                     (_renameKeys != null)) {
176 
177                     String renameKey = _renameKeys.getProperty(key);
178 
179                     if (renameKey != null) {
180                         nativeValue = nativeProps.getProperty(renameKey);
181                         translatedText = props.getProperty(renameKey);
182                     }
183                 }
184 
185                 if ((translatedText != null) &&
186                     ((translatedText.indexOf("Babel Fish") != -1) ||
187                      (translatedText.indexOf("Yahoo! - 999") != -1))) {
188 
189                     translatedText = "";
190                 }
191                 else if ((nativeValue != null) &&
192                          (nativeValue.endsWith(_AUTOMATIC_TRANSLATION))) {
193 
194                     translatedText += _AUTOMATIC_TRANSLATION;
195                 }
196 
197                 if ((translatedText == null) || translatedText.equals("")) {
198                     if (line.indexOf("{") != -1 || line.indexOf("<") != -1) {
199                         translatedText = value + _AUTOMATIC_COPY;
200                     }
201                     else if (key.equals("lang.dir")) {
202                         translatedText = "ltr";
203                     }
204                     else if (key.equals("lang.line.begin")) {
205                         translatedText = "left";
206                     }
207                     else if (key.equals("lang.line.end")) {
208                         translatedText = "right";
209                     }
210                     else if (translationId.equals("en_el") &&
211                              (key.equals("enabled") || key.equals("on") ||
212                               key.equals("on-date"))) {
213 
214                         translatedText = "";
215                     }
216                     else if (translationId.equals("en_es") &&
217                              key.equals("am")) {
218 
219                         translatedText = "";
220                     }
221                     else if (translationId.equals("en_it") &&
222                              key.equals("am")) {
223 
224                         translatedText = "";
225                     }
226                     else if (translationId.equals("en_ja") &&
227                              (key.equals("any") || key.equals("anytime") ||
228                               key.equals("down") || key.equals("on") ||
229                               key.equals("on-date") || key.equals("the"))) {
230 
231                         translatedText = "";
232                     }
233                     else if (translationId.equals("en_ko") &&
234                              key.equals("the")) {
235 
236                         translatedText = "";
237                     }
238                     else {
239                         translatedText = _translate(
240                             translationId, key, value, 0);
241 
242                         if (Validator.isNull(translatedText)) {
243                             translatedText = value + _AUTOMATIC_COPY;
244                         }
245                     }
246                 }
247 
248                 if (Validator.isNotNull(translatedText)) {
249                     if ((translatedText.indexOf("Babel Fish") != -1) ||
250                         (translatedText.indexOf("Yahoo! - 999") != -1)) {
251 
252                         throw new IOException(
253                             "IP was blocked because of over usage. Please " +
254                                 "use another IP.");
255                     }
256 
257                     if (translatedText.indexOf("&#39;") != -1) {
258                         translatedText = StringUtil.replace(
259                             translatedText, "&#39;", "\'");
260                     }
261 
262                     unsyncBufferedWriter.write(key + "=" + translatedText);
263 
264                     unsyncBufferedWriter.newLine();
265                     unsyncBufferedWriter.flush();
266                 }
267                 else if (nativeProps.containsKey(key)) {
268                     unsyncBufferedWriter.write(key + "=");
269 
270                     unsyncBufferedWriter.newLine();
271                     unsyncBufferedWriter.flush();
272                 }
273             }
274             else {
275                 unsyncBufferedWriter.write(line);
276 
277                 unsyncBufferedWriter.newLine();
278                 unsyncBufferedWriter.flush();
279             }
280         }
281 
282         unsyncBufferedReader.close();
283         unsyncBufferedWriter.close();
284     }
285 
286     private String _orderProps(File propsFile) throws IOException {
287         String content = FileUtil.read(propsFile);
288 
289         UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
290             new UnsyncStringReader(content));
291         UnsyncBufferedWriter unsyncBufferedWriter = new UnsyncBufferedWriter(
292             new FileWriter(propsFile));
293 
294         Set<String> messages = new TreeSet<String>();
295 
296         boolean begin = false;
297 
298         String line = null;
299 
300         while ((line = unsyncBufferedReader.readLine()) != null) {
301             int pos = line.indexOf("=");
302 
303             if (pos != -1) {
304                 String key = line.substring(0, pos);
305                 String value = line.substring(pos + 1, line.length());
306 
307                 messages.add(key + "=" + value);
308             }
309             else {
310                 if (begin == true && line.equals("")) {
311                     _sortAndWrite(unsyncBufferedWriter, messages);
312                 }
313 
314                 if (line.equals("")) {
315                     begin = !begin;
316                 }
317 
318                 unsyncBufferedWriter.write(line);
319                 unsyncBufferedWriter.newLine();
320             }
321 
322             unsyncBufferedWriter.flush();
323         }
324 
325         if (messages.size() > 0) {
326             _sortAndWrite(unsyncBufferedWriter, messages);
327         }
328 
329         unsyncBufferedReader.close();
330         unsyncBufferedWriter.close();
331 
332         return FileUtil.read(propsFile);
333     }
334 
335     private void _sortAndWrite(
336             UnsyncBufferedWriter unsyncBufferedWriter, Set<String> messages)
337         throws IOException {
338 
339         String[] messagesArray = messages.toArray(new String[messages.size()]);
340 
341         for (int i = 0; i < messagesArray.length; i++) {
342             unsyncBufferedWriter.write(messagesArray[i]);
343             unsyncBufferedWriter.newLine();
344         }
345 
346         messages.clear();
347     }
348 
349     private String _translate(
350         String translationId, String key, String fromText, int limit) {
351 
352         if (translationId.equals("en_ar") ||
353             translationId.equals("en_eu") ||
354             translationId.equals("en_bg") ||
355             translationId.equals("en_ca") ||
356             translationId.equals("en_cs") ||
357             translationId.equals("en_fi") ||
358             translationId.equals("en_gl") ||
359             translationId.equals("en_hi") ||
360             translationId.equals("en_hu") ||
361             translationId.equals("en_nb") ||
362             translationId.equals("en_fa") ||
363             translationId.equals("en_pl") ||
364             translationId.equals("en_ru") ||
365             translationId.equals("en_sk") ||
366             translationId.equals("en_sv") ||
367             translationId.equals("en_tr") ||
368             translationId.equals("en_vi") ||
369             translationId.equals("en_et")) {
370 
371             // Automatic translator does not support Arabic, Basque, Bulgarian,
372             // Catalan, Czech, Finnish, Galician, Hindi, Hungarian,
373             // Norwegian Bokmål,Persian, Polish, Russian, Slovak, Swedish,
374             // Turkish, or Vietnamese
375 
376             return null;
377         }
378 
379         // Limit the number of retries to 3
380 
381         if (limit == 3) {
382             return null;
383         }
384 
385         String toText = null;
386 
387         try {
388             System.out.println(
389                 "Translating " + translationId + " " + key + " " + fromText);
390 
391             WebCacheItem wci = new TranslationWebCacheItem(
392                 translationId, fromText);
393 
394             Translation translation = (Translation)wci.convert("");
395 
396             toText = translation.getToText();
397 
398             if ((toText != null) &&
399                 (toText.indexOf("Babel Fish") != -1)) {
400 
401                 toText = null;
402             }
403         }
404         catch (Exception e) {
405             e.printStackTrace();
406         }
407 
408         // Keep trying
409 
410         if (toText == null) {
411             return _translate(translationId, key, fromText, ++limit);
412         }
413 
414         if (Validator.isNotNull(toText)) {
415             toText += _AUTOMATIC_TRANSLATION;
416         }
417 
418         return toText;
419     }
420 
421     private static final String _AUTOMATIC_COPY = " (Automatic Copy)";
422 
423     private static final String _AUTOMATIC_TRANSLATION =
424         " (Automatic Translation)";
425 
426     private String _langDir;
427     private String _langFile;
428     private Properties _renameKeys;
429 
430 }