Project: huiswerk
/*
 * Copyright 2010 ZXing authors 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */
 
package com.google.zxing; 
 
import java.io.BufferedReader; 
import java.io.Closeable; 
import java.io.File; 
import java.io.FileFilter; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.io.Reader; 
import java.io.Writer; 
import java.net.URL; 
import java.net.URLEncoder; 
import java.nio.charset.Charset; 
import java.util.Arrays; 
import java.util.Collection; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.SortedMap; 
import java.util.TreeMap; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 
 
/**
 * <p>A utility which auto-translates English strings in Android string resources using 
 * Google Translate.</p> 
 * 
 * <p>Pass the Android client res/ directory as first argument, and optionally message keys 
 * who should be forced to retranslate. 
 * Usage: <code>StringsResourceTranslator android/res/ [key_1 ...]</p> 
 * 
 * @author Sean Owen 
 */
 
public final class StringsResourceTranslator { 
 
  private static final Charset UTF8 = Charset.forName("UTF-8"); 
  private static final Pattern ENTRY_PATTERN = Pattern.compile("<string name=\"([^\"]+)\">([^<]+)</string>"); 
  private static final Pattern STRINGS_FILE_NAME_PATTERN = Pattern.compile("values-(.+)"); 
  private static final Pattern TRANSLATE_RESPONSE_PATTERN = Pattern.compile( 
      "\\{\"translatedText\":\"([^\"]+)\"\\}"); 
 
  private static final String APACHE_2_LICENSE = 
      "<!--\n" + 
      " Copyright (C) 2010 ZXing authors\n" + 
      '\n' + 
      " Licensed under the Apache License, Version 2.0 (the \"License\");\n" + 
      " you may not use this file except in compliance with the License.\n" + 
      " You may obtain a copy of the License at\n" + 
      '\n' + 
      "      http://www.apache.org/licenses/LICENSE-2.0\n" + 
      '\n' + 
      " Unless required by applicable law or agreed to in writing, software\n" + 
      " distributed under the License is distributed on an \"AS IS\" BASIS,\n" + 
      " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" + 
      " See the License for the specific language governing permissions and\n" + 
      " limitations under the License.\n" + 
      " -->\n"
 
  private static final Map<String,String> LANGUAGE_CODE_MASSAGINGS = new HashMap<String,String>(4); 
  static { 
    LANGUAGE_CODE_MASSAGINGS.put("ja-rJP""ja"); 
    LANGUAGE_CODE_MASSAGINGS.put("zh-rCN""zh-cn"); 
    LANGUAGE_CODE_MASSAGINGS.put("zh-rTW""zh-tw"); 
  } 
 
  private StringsResourceTranslator() {} 
 
  public static void main(String[] args) throws IOException { 
 
    File resDir = new File(args[0]); 
    File valueDir = new File(resDir, "values"); 
    File stringsFile = new File(valueDir, "strings.xml"); 
    Collection<String> forceRetranslation = Arrays.asList(args).subList(1, args.length); 
 
    File[] translatedValuesDirs = resDir.listFiles(new FileFilter() { 
      public boolean accept(File file) { 
        return file.isDirectory() && file.getName().startsWith("values-"); 
      } 
    }); 
    for (File translatedValuesDir : translatedValuesDirs) { 
      File translatedStringsFile = new File(translatedValuesDir, "strings.xml"); 
      translate(stringsFile, translatedStringsFile, forceRetranslation); 
    } 
 
  } 
 
  private static void translate(File englishFile, File translatedFile, Collection<String> forceRetranslation) 
      throws IOException { 
 
    SortedMap<String,String> english = readLines(englishFile); 
    SortedMap<String,String> translated = readLines(translatedFile); 
    String parentName = translatedFile.getParentFile().getName(); 
 
    Matcher stringsFileNameMatcher = STRINGS_FILE_NAME_PATTERN.matcher(parentName); 
    stringsFileNameMatcher.find(); 
    String language = stringsFileNameMatcher.group(1); 
    String massagedLanguage = LANGUAGE_CODE_MASSAGINGS.get(language); 
    if (massagedLanguage != null) { 
      language = massagedLanguage; 
    } 
 
    System.out.println("Translating " + language); 
 
    File resultTempFile = File.createTempFile(parentName, ".xml"); 
 
    boolean anyChange = false
    Writer out = null
    try { 
      out = new OutputStreamWriter(new FileOutputStream(resultTempFile), UTF8); 
      out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 
      out.write(APACHE_2_LICENSE); 
      out.write("<resources>\n"); 
 
      for (Map.Entry<String,String> englishEntry : english.entrySet()) { 
        String key = englishEntry.getKey(); 
        out.write("  <string name=\""); 
        out.write(key); 
        out.write("\">"); 
 
        String translatedString = translated.get(key); 
        if (translatedString == null || forceRetranslation.contains(key)) { 
          anyChange = true
          translatedString = translateString(englishEntry.getValue(), language); 
        } 
        out.write(translatedString); 
 
        out.write("</string>\n"); 
      } 
 
      out.write("</resources>\n"); 
      out.flush(); 
 
    } finally { 
      quietClose(out); 
    } 
 
    if (anyChange) { 
      System.out.println("  Writing translations"); 
      translatedFile.delete(); 
      resultTempFile.renameTo(translatedFile); 
    } 
  } 
 
  private static String translateString(String english, String language) throws IOException { 
    System.out.println("  Need translation for " + english); 
    URL translateURL = new URL( 
        "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=" + 
        URLEncoder.encode(english, "UTF-8") + 
        "&langpair=en%7C" + language); 
    StringBuilder translateResult = new StringBuilder(); 
    Reader in = null
    try { 
      in = new InputStreamReader(translateURL.openStream(), UTF8); 
      char[] buffer = new char[1024]; 
      int charsRead; 
      while ((charsRead = in.read(buffer)) > 0) { 
        translateResult.append(buffer, 0, charsRead); 
      } 
    } finally { 
      quietClose(in); 
    } 
    Matcher m = TRANSLATE_RESPONSE_PATTERN.matcher(translateResult); 
    if (!m.find()) { 
      throw new IOException("No translate result"); 
    } 
    String translation = m.group(1); 
    System.out.println("  Got translation " + translation); 
    return translation; 
  } 
 
  private static SortedMap<String,String> readLines(File file) throws IOException { 
    SortedMap<String,String> entries = new TreeMap<String,String>(); 
    BufferedReader reader = null
    try { 
      reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), UTF8)); 
      String line; 
      while ((line = reader.readLine()) != null) { 
        Matcher m = ENTRY_PATTERN.matcher(line); 
        if (m.find()) { 
          String key = m.group(1); 
          String value = m.group(2); 
          entries.put(key, value); 
        } 
      } 
      return entries; 
    } finally { 
      quietClose(reader); 
    } 
  } 
 
  private static void quietClose(Closeable closeable) { 
    if (closeable != null) { 
      try { 
        closeable.close(); 
      } catch (IOException ioe) { 
        // continue 
      } 
    } 
  } 
 
}