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