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