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.io.unsync.UnsyncBufferedReader;
26  import com.liferay.portal.kernel.io.unsync.UnsyncBufferedWriter;
27  import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
28  import com.liferay.portal.kernel.util.FileUtil;
29  import com.liferay.portal.kernel.util.PropertiesUtil;
30  import com.liferay.portal.kernel.util.StringUtil;
31  import com.liferay.portal.kernel.util.Validator;
32  import com.liferay.portal.kernel.webcache.WebCacheItem;
33  import com.liferay.portal.util.InitUtil;
34  import com.liferay.portlet.translator.model.Translation;
35  import com.liferay.portlet.translator.util.TranslationWebCacheItem;
36  
37  import java.io.File;
38  import java.io.FileInputStream;
39  import java.io.FileWriter;
40  import java.io.IOException;
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         UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
157             new UnsyncStringReader(content));
158         UnsyncBufferedWriter unsyncBufferedWriter = new UnsyncBufferedWriter(
159             new FileWriter(nativePropsFile));
160 
161         String line = null;
162 
163         while ((line = unsyncBufferedReader.readLine()) != null) {
164             line = line.trim();
165 
166             int pos = line.indexOf("=");
167 
168             if (pos != -1) {
169                 String key = line.substring(0, pos);
170                 String value = line.substring(pos + 1, line.length());
171 
172                 String translatedText = props.getProperty(key);
173 
174                 if ((translatedText == null) && (_renameKeys != null)) {
175                     String renameKey = _renameKeys.getProperty(key);
176 
177                     if (renameKey != null) {
178                         translatedText = props.getProperty(renameKey);
179                     }
180                 }
181 
182                 if ((translatedText != null) &&
183                     ((translatedText.indexOf("Babel Fish") != -1) ||
184                      (translatedText.indexOf("Yahoo! - 999") != -1))) {
185 
186                     translatedText = "";
187                 }
188 
189                 if ((translatedText == null) || translatedText.equals("")) {
190                     if (line.indexOf("{") != -1 || line.indexOf("<") != -1) {
191                         translatedText = value;
192                     }
193                     else if (key.equals("lang.dir")) {
194                         translatedText = "ltr";
195                     }
196                     else if (key.equals("lang.line.begin")) {
197                         translatedText = "left";
198                     }
199                     else if (key.equals("lang.line.end")) {
200                         translatedText = "right";
201                     }
202                     else if (translationId.equals("en_el") &&
203                              (key.equals("enabled") || key.equals("on") ||
204                               key.equals("on-date"))) {
205 
206                         translatedText = "";
207                     }
208                     else if (translationId.equals("en_es") &&
209                              key.equals("am")) {
210 
211                         translatedText = "";
212                     }
213                     else if (translationId.equals("en_it") &&
214                              key.equals("am")) {
215 
216                         translatedText = "";
217                     }
218                     else if (translationId.equals("en_ja") &&
219                              (key.equals("any") || key.equals("anytime") ||
220                               key.equals("down") || key.equals("on") ||
221                               key.equals("the"))) {
222 
223                         translatedText = "";
224                     }
225                     else if (translationId.equals("en_ko") &&
226                              key.equals("the")) {
227 
228                         translatedText = "";
229                     }
230                     else {
231                         translatedText = _translate(translationId, value, 0);
232                     }
233                 }
234 
235                 if (Validator.isNotNull(translatedText)) {
236                     if ((translatedText.indexOf("Babel Fish") != -1) ||
237                         (translatedText.indexOf("Yahoo! - 999") != -1)) {
238 
239                         throw new IOException(
240                             "IP was blocked because of over usage. Please " +
241                                 "use another IP.");
242                     }
243 
244                     if (translatedText.indexOf("&#39;") != -1) {
245                         translatedText = StringUtil.replace(
246                             translatedText, "&#39;", "\'");
247                     }
248 
249                     unsyncBufferedWriter.write(key + "=" + translatedText);
250 
251                     unsyncBufferedWriter.newLine();
252                     unsyncBufferedWriter.flush();
253                 }
254                 else if (nativeProps.containsKey(key)) {
255                     unsyncBufferedWriter.write(key + "=");
256 
257                     unsyncBufferedWriter.newLine();
258                     unsyncBufferedWriter.flush();
259                 }
260             }
261             else {
262                 unsyncBufferedWriter.write(line);
263 
264                 unsyncBufferedWriter.newLine();
265                 unsyncBufferedWriter.flush();
266             }
267         }
268 
269         unsyncBufferedReader.close();
270         unsyncBufferedWriter.close();
271     }
272 
273     private String _orderProps(File propsFile) throws IOException {
274         String content = FileUtil.read(propsFile);
275 
276         UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
277             new UnsyncStringReader(content));
278         UnsyncBufferedWriter unsyncBufferedWriter = new UnsyncBufferedWriter(
279             new FileWriter(propsFile));
280 
281         Set<String> messages = new TreeSet<String>();
282 
283         boolean begin = false;
284 
285         String line = null;
286 
287         while ((line = unsyncBufferedReader.readLine()) != null) {
288             int pos = line.indexOf("=");
289 
290             if (pos != -1) {
291                 String key = line.substring(0, pos);
292                 String value = line.substring(pos + 1, line.length());
293 
294                 messages.add(key + "=" + value);
295             }
296             else {
297                 if (begin == true && line.equals("")) {
298                     _sortAndWrite(unsyncBufferedWriter, messages);
299                 }
300 
301                 if (line.equals("")) {
302                     begin = !begin;
303                 }
304 
305                 unsyncBufferedWriter.write(line);
306                 unsyncBufferedWriter.newLine();
307             }
308 
309             unsyncBufferedWriter.flush();
310         }
311 
312         if (messages.size() > 0) {
313             _sortAndWrite(unsyncBufferedWriter, messages);
314         }
315 
316         unsyncBufferedReader.close();
317         unsyncBufferedWriter.close();
318 
319         return FileUtil.read(propsFile);
320     }
321 
322     private void _sortAndWrite(
323             UnsyncBufferedWriter unsyncBufferedWriter, Set<String> messages)
324         throws IOException {
325 
326         String[] messagesArray = messages.toArray(new String[messages.size()]);
327 
328         for (int i = 0; i < messagesArray.length; i++) {
329             unsyncBufferedWriter.write(messagesArray[i]);
330             unsyncBufferedWriter.newLine();
331         }
332 
333         messages.clear();
334     }
335 
336     private String _translate(
337         String translationId, String fromText, int limit) {
338 
339         if (translationId.equals("en_ar") ||
340             translationId.equals("en_eu") ||
341             translationId.equals("en_ca") ||
342             translationId.equals("en_cs") ||
343             translationId.equals("en_fi") ||
344             translationId.equals("en_hu") ||
345             translationId.equals("en_nb") ||
346             translationId.equals("en_fa") ||
347             translationId.equals("en_pl") ||
348             translationId.equals("en_ru") ||
349             translationId.equals("en_sk") ||
350             translationId.equals("en_sv") ||
351             translationId.equals("en_tr") ||
352             translationId.equals("en_vi")) {
353 
354             // Automatic translator does not support Arabic, Basque, Catalan,
355             // Czech, Finnish, Hungarian, Norwegian Bokmål, Persian, Polish,
356             // Russian, Slovak, Swedish, Turkish, or Vietnamese
357 
358             return null;
359         }
360 
361         // Limit the number of retries to 3
362 
363         if (limit == 3) {
364             return null;
365         }
366 
367         String toText = null;
368 
369         try {
370             System.out.println("Translating " + translationId + " " + fromText);
371 
372             WebCacheItem wci = new TranslationWebCacheItem(
373                 translationId, fromText);
374 
375             Translation translation = (Translation)wci.convert("");
376 
377             toText = translation.getToText();
378 
379             if ((toText != null) &&
380                 (toText.indexOf("Babel Fish") != -1)) {
381 
382                 toText = null;
383             }
384         }
385         catch (Exception e) {
386             e.printStackTrace();
387         }
388 
389         // Keep trying
390 
391         if (toText == null) {
392             return _translate(translationId, fromText, ++limit);
393         }
394 
395         return toText;
396     }
397 
398     private String _langDir;
399     private String _langFile;
400     private Properties _renameKeys;
401 
402 }