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