1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.tools;
24  
25  import com.liferay.portal.kernel.util.FileUtil;
26  import com.liferay.portal.kernel.util.StringUtil;
27  import com.liferay.portal.kernel.util.Validator;
28  import com.liferay.portal.kernel.webcache.WebCacheItem;
29  import com.liferay.portal.util.InitUtil;
30  import com.liferay.portlet.translator.model.Translation;
31  import com.liferay.portlet.translator.util.TranslationWebCacheItem;
32  
33  import java.io.BufferedReader;
34  import java.io.BufferedWriter;
35  import java.io.File;
36  import java.io.FileInputStream;
37  import java.io.FileWriter;
38  import java.io.IOException;
39  import java.io.StringReader;
40  
41  import java.util.Properties;
42  import java.util.Set;
43  import java.util.TreeSet;
44  
45  /**
46   * <a href="LangBuilder.java.html"><b><i>View Source</i></b></a>
47   *
48   * @author Brian Wing Shun Chan
49   *
50   */
51  public class LangBuilder {
52  
53      public static void main(String[] args) {
54          InitUtil.initWithSpring();
55  
56          if (args.length == 2) {
57              new LangBuilder(args[0], args[1]);
58          }
59          else {
60              throw new IllegalArgumentException();
61          }
62      }
63  
64      public LangBuilder(String langDir, String langFile) {
65          try {
66              _langDir = langDir;
67              _langFile = langFile;
68  
69              String content = _orderProps(
70                  new File(_langDir + "/" + _langFile + ".properties"));
71  
72              _createProps(content, "ar"); // Arabic
73              _createProps(content, "eu"); // Basque
74              _createProps(content, "ca"); // Catalan
75              _createProps(content, "zh_CN"); // Chinese (China)
76              _createProps(content, "zh_TW"); // Chinese (Taiwan)
77              _createProps(content, "cs"); // Czech
78              _createProps(content, "nl"); // Dutch
79              _createProps(content, "fi"); // Finnish
80              _createProps(content, "fr"); // French
81              _createProps(content, "de"); // German
82              _createProps(content, "el"); // Greek
83              _createProps(content, "hu"); // Hungarian
84              _createProps(content, "it"); // Italian
85              _createProps(content, "ja"); // Japanese
86              _createProps(content, "ko"); // Korean
87              _createProps(content, "nb"); // Norwegian Bokmål
88              _createProps(content, "fa"); // Persian
89              _createProps(content, "pl"); // Polish
90              _createProps(content, "pt_BR"); // Brazilian Portuguese
91              _createProps(content, "pt_PT"); // Portuguese
92              _createProps(content, "ru"); // Russian
93              _createProps(content, "sk"); // Slovak
94              _createProps(content, "es"); // Spanish
95              _createProps(content, "sv"); // Swedish
96              _createProps(content, "tr"); // Turkish
97              _createProps(content, "vi"); // Vietnamese
98          }
99          catch (Exception e) {
100             e.printStackTrace();
101         }
102     }
103 
104     private void _createProps(String content, String languageId)
105         throws IOException {
106 
107         File propsFile = new File(
108             _langDir + "/" + _langFile + "_" + languageId + ".properties");
109 
110         Properties props = new Properties();
111 
112         if (propsFile.exists()) {
113             props.load(new FileInputStream(propsFile));
114         }
115 
116         File nativePropsFile = new File(
117             _langDir + "/" + _langFile + "_" + languageId +
118                 ".properties.native");
119 
120         Properties nativeProps = new Properties();
121 
122         if (nativePropsFile.exists()) {
123             nativeProps.load(new FileInputStream(nativePropsFile));
124         }
125 
126         String translationId = "en_" + languageId;
127 
128         if (translationId.equals("en_pt_BR")) {
129             translationId = "en_pt";
130         }
131         else if (translationId.equals("en_pt_PT")) {
132             translationId = "en_pt";
133         }
134         else if (translationId.equals("en_zh_CN")) {
135             translationId = "en_zh";
136         }
137         else if (translationId.equals("en_zh_TW")) {
138             translationId = "en_zt";
139         }
140 
141         BufferedReader br = new BufferedReader(new StringReader(content));
142         BufferedWriter bw = new BufferedWriter(new FileWriter(nativePropsFile));
143 
144         String line = null;
145 
146         while ((line = br.readLine()) != null) {
147             line = line.trim();
148 
149             int pos = line.indexOf("=");
150 
151             if (pos != -1) {
152                 String key = line.substring(0, pos);
153                 String value = line.substring(pos + 1, line.length());
154 
155                 String translatedText = props.getProperty(key);
156 
157                 if ((translatedText != null) &&
158                     ((translatedText.indexOf("Babel Fish") != -1) ||
159                      (translatedText.indexOf("Yahoo! - 999") != -1))) {
160 
161                     translatedText = "";
162                 }
163 
164                 if ((translatedText == null) || translatedText.equals("")) {
165                     if (line.indexOf("{") != -1 || line.indexOf("<") != -1) {
166                         translatedText = value;
167                     }
168                     else if (key.equals("lang.dir")) {
169                         translatedText = "ltr";
170                     }
171                     else if (key.equals("lang.line.begin")) {
172                         translatedText = "left";
173                     }
174                     else if (key.equals("lang.line.end")) {
175                         translatedText = "right";
176                     }
177                     else {
178                         translatedText = _translate(translationId, value, 0);
179                     }
180                 }
181 
182                 if (Validator.isNotNull(translatedText)) {
183                     if (translatedText.indexOf("&#39;") != -1) {
184                         translatedText = StringUtil.replace(
185                             translatedText, "&#39;", "\'");
186                     }
187 
188                     bw.write(key + "=" + translatedText);
189 
190                     bw.newLine();
191                     bw.flush();
192                 }
193                 else if (nativeProps.containsKey(key)) {
194                     bw.write(key + "=");
195 
196                     bw.newLine();
197                     bw.flush();
198                 }
199             }
200             else {
201                 bw.write(line);
202 
203                 bw.newLine();
204                 bw.flush();
205             }
206         }
207 
208         br.close();
209         bw.close();
210     }
211 
212     private String _orderProps(File propsFile) throws IOException {
213         String content = FileUtil.read(propsFile);
214 
215         BufferedReader br = new BufferedReader(new StringReader(content));
216         BufferedWriter bw = new BufferedWriter(new FileWriter(propsFile));
217 
218         Set<String> messages = new TreeSet<String>();
219 
220         boolean begin = false;
221 
222         String line = null;
223 
224         while ((line = br.readLine()) != null) {
225             int pos = line.indexOf("=");
226 
227             if (pos != -1) {
228                 String key = line.substring(0, pos);
229                 String value = line.substring(pos + 1, line.length());
230 
231                 messages.add(key + "=" + value);
232             }
233             else {
234                 if (begin == true && line.equals("")) {
235                     _sortAndWrite(bw, messages);
236                 }
237 
238                 if (line.equals("")) {
239                     begin = !begin;
240                 }
241 
242                 bw.write(line);
243                 bw.newLine();
244             }
245 
246             bw.flush();
247         }
248 
249         if (messages.size() > 0) {
250             _sortAndWrite(bw, messages);
251         }
252 
253         br.close();
254         bw.close();
255 
256         return FileUtil.read(propsFile);
257     }
258 
259     private void _sortAndWrite(BufferedWriter bw, Set<String> messages)
260         throws IOException {
261 
262         String[] messagesArray = messages.toArray(new String[messages.size()]);
263 
264         for (int i = 0; i < messagesArray.length; i++) {
265             bw.write(messagesArray[i]);
266             bw.newLine();
267         }
268 
269         messages.clear();
270     }
271 
272     private String _translate(
273         String translationId, String fromText, int limit) {
274 
275         if (translationId.equals("en_ar") ||
276             translationId.equals("en_eu") ||
277             translationId.equals("en_ca") ||
278             translationId.equals("en_cs") ||
279             translationId.equals("en_fi") ||
280             translationId.equals("en_hu") ||
281             translationId.equals("en_nb") ||
282             translationId.equals("en_fa") ||
283             translationId.equals("en_pl") ||
284             translationId.equals("en_ru") ||
285             translationId.equals("en_sk") ||
286             translationId.equals("en_sv") ||
287             translationId.equals("en_tr") ||
288             translationId.equals("en_vi")) {
289 
290             // Automatic translator does not support Arabic, Basque, Catalan,
291             // Czech, Finnish, Hungarian, Norwegian Bokmål, Persian, Polish,
292             // Russian, Slovak, Swedish, Turkish, or Vietnamese
293 
294             return null;
295         }
296 
297         // Limit the number of retries to 3
298 
299         if (limit == 3) {
300             return null;
301         }
302 
303         String toText = null;
304 
305         try {
306             System.out.println("Translating " + translationId + " " + fromText);
307 
308             WebCacheItem wci = new TranslationWebCacheItem(
309                 translationId, fromText);
310 
311             Translation translation = (Translation)wci.convert("");
312 
313             toText = translation.getToText();
314 
315             if ((toText != null) &&
316                 (toText.indexOf("Babel Fish") != -1)) {
317 
318                 toText = null;
319             }
320         }
321         catch (Exception e) {
322             e.printStackTrace();
323         }
324 
325         // Keep trying
326 
327         if (toText == null) {
328             return _translate(translationId, fromText, ++limit);
329         }
330 
331         return toText;
332     }
333 
334     private String _langDir;
335     private String _langFile;
336 
337 }