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