001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.tools;
016    
017    import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
018    import com.liferay.portal.kernel.io.unsync.UnsyncBufferedWriter;
019    import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
020    import com.liferay.portal.kernel.util.FileUtil;
021    import com.liferay.portal.kernel.util.PropertiesUtil;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.StringUtil;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.kernel.webcache.WebCacheItem;
026    import com.liferay.portal.util.InitUtil;
027    import com.liferay.portlet.translator.model.Translation;
028    import com.liferay.portlet.translator.util.TranslationWebCacheItem;
029    
030    import java.io.File;
031    import java.io.FileInputStream;
032    import java.io.FileWriter;
033    import java.io.IOException;
034    
035    import java.util.Properties;
036    import java.util.Set;
037    import java.util.TreeSet;
038    
039    /**
040     * @author Brian Wing Shun Chan
041     */
042    public class LangBuilder {
043    
044            public static final String AUTOMATIC_COPY = " (Automatic Copy)";
045    
046            public static final String AUTOMATIC_TRANSLATION =
047                    " (Automatic Translation)";
048    
049            public static void main(String[] args) {
050                    InitUtil.initWithSpring();
051    
052                    if (args.length == 2) {
053                            new LangBuilder(args[0], args[1], null);
054                    }
055                    else if (args.length == 3) {
056                            new LangBuilder(args[0], args[1], args[2]);
057                    }
058                    else {
059                            throw new IllegalArgumentException();
060                    }
061            }
062    
063            public LangBuilder(String langDir, String langFile, String langCode) {
064                    try {
065                            _langDir = langDir;
066                            _langFile = langFile;
067    
068                            File renameKeysFile = new File(_langDir + "/rename.properties");
069    
070                            if (renameKeysFile.exists()) {
071                                    _renameKeys = PropertiesUtil.load(
072                                            FileUtil.read(renameKeysFile));
073                            }
074    
075                            String content = _orderProperties(
076                                    new File(_langDir + "/" + _langFile + ".properties"));
077    
078                            if (Validator.isNotNull(langCode) && !langCode.startsWith("$")) {
079                                    _createProperties(content, langCode);
080                            }
081                            else {
082                                    _createProperties(content, "ar"); // Arabic
083                                    _createProperties(content, "eu"); // Basque
084                                    _createProperties(content, "bg"); // Bulgarian
085                                    _createProperties(content, "ca"); // Catalan
086                                    _createProperties(content, "zh_CN"); // Chinese (China)
087                                    _createProperties(content, "zh_TW"); // Chinese (Taiwan)
088                                    _createProperties(content, "cs"); // Czech
089                                    _createProperties(content, "nl"); // Dutch
090                                    _createProperties(content, "et"); // Estonian
091                                    _createProperties(content, "fi"); // Finnish
092                                    _createProperties(content, "fr"); // French
093                                    _createProperties(content, "gl"); // Galician
094                                    _createProperties(content, "de"); // German
095                                    _createProperties(content, "el"); // Greek
096                                    _createProperties(content, "iw"); // Hebrew
097                                    _createProperties(content, "hi_IN"); // Hindi (India)
098                                    _createProperties(content, "hu"); // Hungarian
099                                    _createProperties(content, "in"); // Indonesian
100                                    _createProperties(content, "it"); // Italian
101                                    _createProperties(content, "ja"); // Japanese
102                                    _createProperties(content, "ko"); // Korean
103                                    _createProperties(content, "nb"); // Norwegian Bokmål
104                                    _createProperties(content, "fa"); // Persian
105                                    _createProperties(content, "pl"); // Polish
106                                    _createProperties(content, "pt_BR"); // Portuguese (Brazil)
107                                    _createProperties(content, "pt_PT"); // Portuguese (Portugal)
108                                    _createProperties(content, "ru"); // Russian
109                                    _createProperties(content, "sk"); // Slovak
110                                    _createProperties(content, "es"); // Spanish
111                                    _createProperties(content, "sv"); // Swedish
112                                    _createProperties(content, "tr"); // Turkish
113                                    _createProperties(content, "uk"); // Ukrainian
114                                    _createProperties(content, "vi"); // Vietnamese
115                            }
116                    }
117                    catch (Exception e) {
118                            e.printStackTrace();
119                    }
120            }
121    
122            private void _createProperties(String content, String languageId)
123                    throws IOException {
124    
125                    File propertiesFile = new File(
126                            _langDir + "/" + _langFile + "_" + languageId + ".properties");
127    
128                    Properties properties = new Properties();
129    
130                    if (propertiesFile.exists()) {
131                            properties.load(new FileInputStream(propertiesFile));
132                    }
133    
134                    String translationId = "en_" + languageId;
135    
136                    if (translationId.equals("en_pt_BR")) {
137                            translationId = "en_pt";
138                    }
139                    else if (translationId.equals("en_pt_PT")) {
140                            translationId = "en_pt";
141                    }
142                    else if (translationId.equals("en_zh_CN")) {
143                            translationId = "en_zh";
144                    }
145                    else if (translationId.equals("en_zh_TW")) {
146                            translationId = "en_zt";
147                    }
148                    else if (translationId.equals("en_hi_IN")) {
149                            translationId = "en_hi";
150                    }
151    
152                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
153                            new UnsyncStringReader(content));
154                    UnsyncBufferedWriter unsyncBufferedWriter = new UnsyncBufferedWriter(
155                            new FileWriter(propertiesFile));
156    
157                    String line = null;
158    
159                    while ((line = unsyncBufferedReader.readLine()) != null) {
160                            line = line.trim();
161    
162                            int pos = line.indexOf("=");
163    
164                            if (pos != -1) {
165                                    String key = line.substring(0, pos);
166                                    String value = line.substring(pos + 1, line.length());
167    
168                                    String translatedText = _getProperty(properties, key);
169    
170                                    if ((translatedText == null) && (_renameKeys != null)) {
171                                            String renameKey = _renameKeys.getProperty(key);
172    
173                                            if (renameKey != null) {
174                                                    translatedText = _getProperty(properties, key);
175                                            }
176                                    }
177    
178                                    if ((translatedText != null) &&
179                                            ((translatedText.indexOf("Babel Fish") != -1) ||
180                                             (translatedText.indexOf("Yahoo! - 999") != -1))) {
181    
182                                            translatedText = "";
183                                    }
184    
185                                    if ((translatedText == null) || translatedText.equals("")) {
186                                            if (line.indexOf("{") != -1 || line.indexOf("<") != -1) {
187                                                    translatedText = value + AUTOMATIC_COPY;
188                                            }
189                                            else if (line.indexOf("[") != -1) {
190                                                    pos = line.indexOf("[");
191    
192                                                    String baseKey = line.substring(0, pos);
193    
194                                                    translatedText =
195                                                            _getProperty(properties, baseKey) + AUTOMATIC_COPY;
196                                            }
197                                            else if (key.equals("lang.dir")) {
198                                                    translatedText = "ltr";
199                                            }
200                                            else if (key.equals("lang.line.begin")) {
201                                                    translatedText = "left";
202                                            }
203                                            else if (key.equals("lang.line.end")) {
204                                                    translatedText = "right";
205                                            }
206                                            else if (translationId.equals("en_el") &&
207                                                             (key.equals("enabled") || key.equals("on") ||
208                                                              key.equals("on-date"))) {
209    
210                                                    translatedText = "";
211                                            }
212                                            else if (translationId.equals("en_es") &&
213                                                             key.equals("am")) {
214    
215                                                    translatedText = "";
216                                            }
217                                            else if (translationId.equals("en_it") &&
218                                                             key.equals("am")) {
219    
220                                                    translatedText = "";
221                                            }
222                                            else if (translationId.equals("en_ja") &&
223                                                             (key.equals("any") || key.equals("anytime") ||
224                                                              key.equals("down") || key.equals("on") ||
225                                                              key.equals("on-date") || key.equals("the"))) {
226    
227                                                    translatedText = "";
228                                            }
229                                            else if (translationId.equals("en_ko") &&
230                                                             key.equals("the")) {
231    
232                                                    translatedText = "";
233                                            }
234                                            else {
235                                                    translatedText = _translate(
236                                                            translationId, key, value, 0);
237    
238                                                    if (Validator.isNull(translatedText)) {
239                                                            translatedText = value + AUTOMATIC_COPY;
240                                                    }
241                                                    else {
242                                                            translatedText = value + AUTOMATIC_TRANSLATION;
243                                                    }
244                                            }
245                                    }
246    
247                                    if (Validator.isNotNull(translatedText)) {
248                                            if ((translatedText.indexOf("Babel Fish") != -1) ||
249                                                    (translatedText.indexOf("Yahoo! - 999") != -1)) {
250    
251                                                    throw new IOException(
252                                                            "IP was blocked because of over usage. Please " +
253                                                                    "use another IP.");
254                                            }
255    
256                                            if (translatedText.indexOf("&#39;") != -1) {
257                                                    translatedText = StringUtil.replace(
258                                                            translatedText, "&#39;", "\'");
259                                            }
260    
261                                            translatedText = StringUtil.replace(
262                                                    translatedText.trim(), "  ", " ");
263    
264                                            unsyncBufferedWriter.write(key + "=" + translatedText);
265    
266                                            unsyncBufferedWriter.newLine();
267                                            unsyncBufferedWriter.flush();
268                                    }
269                            }
270                            else {
271                                    unsyncBufferedWriter.write(line);
272    
273                                    unsyncBufferedWriter.newLine();
274                                    unsyncBufferedWriter.flush();
275                            }
276                    }
277    
278                    unsyncBufferedReader.close();
279                    unsyncBufferedWriter.close();
280            }
281    
282            private String _getProperty(Properties properties, String key)
283                    throws IOException {
284    
285                    String value = properties.getProperty(key);
286    
287                    if (Validator.isNotNull(value)) {
288                            value = new String(
289                                    value.getBytes(StringPool.ISO_8859_1),
290                                    StringPool.UTF8);
291                    }
292    
293                    return value;
294            }
295    
296            private String _orderProperties(File propertiesFile) throws IOException {
297                    String content = FileUtil.read(propertiesFile);
298    
299                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
300                            new UnsyncStringReader(content));
301                    UnsyncBufferedWriter unsyncBufferedWriter = new UnsyncBufferedWriter(
302                            new FileWriter(propertiesFile));
303    
304                    Set<String> messages = new TreeSet<String>();
305    
306                    boolean begin = false;
307    
308                    String line = null;
309    
310                    while ((line = unsyncBufferedReader.readLine()) != null) {
311                            int pos = line.indexOf("=");
312    
313                            if (pos != -1) {
314                                    String key = line.substring(0, pos);
315                                    String value = line.substring(pos + 1, line.length());
316    
317                                    messages.add(key + "=" + value);
318                            }
319                            else {
320                                    if (begin == true && line.equals("")) {
321                                            _sortAndWrite(unsyncBufferedWriter, messages);
322                                    }
323    
324                                    if (line.equals("")) {
325                                            begin = !begin;
326                                    }
327    
328                                    unsyncBufferedWriter.write(line);
329                                    unsyncBufferedWriter.newLine();
330                            }
331    
332                            unsyncBufferedWriter.flush();
333                    }
334    
335                    if (messages.size() > 0) {
336                            _sortAndWrite(unsyncBufferedWriter, messages);
337                    }
338    
339                    unsyncBufferedReader.close();
340                    unsyncBufferedWriter.close();
341    
342                    return FileUtil.read(propertiesFile);
343            }
344    
345            private void _sortAndWrite(
346                            UnsyncBufferedWriter unsyncBufferedWriter, Set<String> messages)
347                    throws IOException {
348    
349                    String[] messagesArray = messages.toArray(new String[messages.size()]);
350    
351                    for (int i = 0; i < messagesArray.length; i++) {
352                            unsyncBufferedWriter.write(messagesArray[i]);
353                            unsyncBufferedWriter.newLine();
354                    }
355    
356                    messages.clear();
357            }
358    
359            private String _translate(
360                    String translationId, String key, String fromText, int limit) {
361    
362                    if (translationId.equals("en_ar") ||
363                            translationId.equals("en_eu") ||
364                            translationId.equals("en_bg") ||
365                            translationId.equals("en_ca") ||
366                            translationId.equals("en_cs") ||
367                            translationId.equals("en_fi") ||
368                            translationId.equals("en_gl") ||
369                            translationId.equals("en_iw") ||
370                            translationId.equals("en_hi") ||
371                            translationId.equals("en_hu") ||
372                            translationId.equals("en_in") ||
373                            translationId.equals("en_nb") ||
374                            translationId.equals("en_fa") ||
375                            translationId.equals("en_pl") ||
376                            translationId.equals("en_ru") ||
377                            translationId.equals("en_sk") ||
378                            translationId.equals("en_sv") ||
379                            translationId.equals("en_tr") ||
380                            translationId.equals("en_uk") ||
381                            translationId.equals("en_vi") ||
382                            translationId.equals("en_et")) {
383    
384                            // Automatic translator does not support Arabic, Basque, Bulgarian,
385                            // Catalan, Czech, Finnish, Galician, Hebrew, Hindi, Hungarian,
386                            // Indonesian, Norwegian Bokmål,Persian, Polish, Russian, Slovak,
387                            // Swedish, Turkish, Ukrainian, or Vietnamese
388    
389                            return null;
390                    }
391    
392                    // Limit the number of retries to 3
393    
394                    if (limit == 3) {
395                            return null;
396                    }
397    
398                    String toText = null;
399    
400                    try {
401                            System.out.println(
402                                    "Translating " + translationId + " " + key + " " + fromText);
403    
404                            WebCacheItem wci = new TranslationWebCacheItem(
405                                    translationId, fromText);
406    
407                            Translation translation = (Translation)wci.convert("");
408    
409                            toText = translation.getToText();
410    
411                            if ((toText != null) &&
412                                    (toText.indexOf("Babel Fish") != -1)) {
413    
414                                    toText = null;
415                            }
416                    }
417                    catch (Exception e) {
418                            e.printStackTrace();
419                    }
420    
421                    // Keep trying
422    
423                    if (toText == null) {
424                            return _translate(translationId, key, fromText, ++limit);
425                    }
426    
427                    if (Validator.isNotNull(toText)) {
428                            toText += AUTOMATIC_TRANSLATION;
429                    }
430    
431                    return toText;
432            }
433    
434            private String _langDir;
435            private String _langFile;
436            private Properties _renameKeys;
437    
438    }