| /* |
| * Copyright 2010 Google Inc. |
| * |
| * 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.gwt.tools.cldr; |
| |
| import com.google.gwt.codegen.server.AbortablePrintWriter; |
| import com.google.gwt.codegen.server.JavaSourceWriterBuilder; |
| import com.google.gwt.codegen.server.LoggingCodeGenContext; |
| import com.google.gwt.i18n.shared.GwtLocale; |
| |
| import org.unicode.cldr.util.Factory; |
| |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.OutputStreamWriter; |
| import java.io.PrintWriter; |
| import java.util.Calendar; |
| import java.util.Map; |
| |
| /** |
| * Base class for CLDR processors that generate GWT i18n resources. |
| */ |
| public abstract class Processor { |
| |
| /** |
| * A CodeGenContext implementation that logs to j.u.logging and creates |
| * output files using {@link Processor#createOutputFile(String, String)}. |
| */ |
| protected class ProcessorCodeGenContext extends LoggingCodeGenContext { |
| @Override |
| public JavaSourceWriterBuilder addClass(String superPkg, String pkgName, String className) { |
| String pkgPath = superPkg == null ? pkgName : superPkg + '/' + pkgName; |
| if (pkgPath.length() > 0) { |
| pkgPath = pkgPath.replace('.', '/') + '/'; |
| } |
| String classPath = className.replace('.', '_'); |
| String fileName = pkgPath + classPath + ".java"; |
| try { |
| PrintWriter pw = createOutputFile("", fileName); |
| AbortablePrintWriter apw = new AbortablePrintWriter(pw); |
| printHeader(apw); |
| return new JavaSourceWriterBuilder(apw, pkgName, className); |
| } catch (FileNotFoundException e) { |
| error("Unable to create " + fileName, e); |
| return null; |
| } catch (IOException e) { |
| error("Unable to create " + fileName, e); |
| return null; |
| } |
| } |
| } |
| |
| protected static final String I18N_PACKAGE_PATH = "user/src/com/google/gwt/i18n/"; |
| |
| protected static <T> String join(String joiner, Iterable<T> objects) { |
| StringBuilder buf = new StringBuilder(); |
| for (Object obj : objects) { |
| if (buf.length() > 0) { |
| buf.append(joiner); |
| } |
| buf.append(obj.toString()); |
| } |
| return buf.toString(); |
| } |
| |
| protected static String localeSuffix(GwtLocale locale) { |
| return (locale.isDefault() ? "" : "_") + locale.getAsString(); |
| } |
| |
| /** |
| * @param value |
| * @return value with all quotes escaped |
| */ |
| protected static String quote(String value) { |
| return value.replace("\"", "\\\""); |
| } |
| |
| protected final Factory cldrFactory; |
| |
| protected final LocaleData localeData; |
| |
| protected final File outputDir; |
| |
| private boolean useOverride; |
| |
| /** |
| * Initialize the shared portion of a Processor. |
| * |
| * @param outputDir output directory for created files |
| * @param cldrFactory CLDR factory used to create new CLDRFile instances |
| * @param localeData LocaleData instance to collect data from CLDR files |
| */ |
| protected Processor(File outputDir, Factory cldrFactory, LocaleData localeData) { |
| this.outputDir = outputDir; |
| this.cldrFactory = cldrFactory; |
| this.localeData = localeData; |
| useOverride = true; |
| } |
| |
| /** |
| * Execute this processor. |
| * |
| * It will call loadData, cleanupData, writeOutputFiles, and then reset on its |
| * localeData instance. |
| * |
| * @throws IOException |
| */ |
| public final void run() throws IOException { |
| try { |
| loadData(); |
| cleanupData(); |
| writeOutputFiles(); |
| } finally { |
| localeData.reset(); |
| } |
| } |
| |
| /** |
| * Override hook for subclasses to implement any cleanup needed, such as |
| * removing values which duplicate those from ancestors. |
| */ |
| protected void cleanupData() { |
| // do nothing by default |
| } |
| |
| /** |
| * Create an output file including any parent directories. |
| * |
| * @param name name of file, which will be prefixed by |
| * user/src/com/google/gwt/i18n/client/impl/cldr |
| * @param ext extension for file |
| * @param locale locale name or null if not localized |
| * @return a PrintWriter instance |
| * @throws IOException |
| */ |
| protected PrintWriter createFile(String name, String ext, String locale) throws IOException { |
| if (locale == null || locale.length() == 0) { |
| locale = ""; |
| } else { |
| locale = "_" + locale; |
| } |
| return createOutputFile("client/impl/cldr/" + name + locale + "." + ext); |
| } |
| |
| protected PrintWriter createOutputFile(String suffix) throws IOException, FileNotFoundException { |
| return createOutputFile(I18N_PACKAGE_PATH, suffix); |
| } |
| |
| protected PrintWriter createOutputFile(String prefix, String suffix) throws IOException, |
| FileNotFoundException { |
| PrintWriter pw; |
| File f = new File(outputDir, prefix + suffix); |
| File parent = f.getParentFile(); |
| if (parent != null) { |
| parent.mkdirs(); |
| } |
| f.createNewFile(); |
| pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), |
| "UTF-8")), false); |
| return pw; |
| } |
| |
| protected void generateIntMethod(PrintWriter pw, String category, GwtLocale locale, String key, |
| String method) { |
| String value = localeData.getEntry(category, locale, key); |
| if (value != null) { |
| pw.println(); |
| if (useOverride) { |
| pw.println(" @Override"); |
| } |
| pw.println(" public int " + method + "() {"); |
| pw.println(" return " + value + ";"); |
| pw.println(" }"); |
| } |
| } |
| |
| protected void generateStringMethod(PrintWriter pw, String category, GwtLocale locale, |
| String key, String method) { |
| String value = localeData.getEntry(category, locale, key); |
| generateStringValue(pw, method, value); |
| } |
| |
| protected void generateStringValue(PrintWriter pw, String method, String value) { |
| if (value != null) { |
| pw.println(); |
| if (useOverride) { |
| pw.println(" @Override"); |
| } |
| pw.println(" public String " + method + "() {"); |
| pw.println(" return \"" + quote(value) + "\";"); |
| pw.println(" }"); |
| } |
| } |
| |
| /** |
| * @return true if generated methods should use @Override. |
| */ |
| protected boolean getOverrides() { |
| return useOverride; |
| } |
| |
| /** |
| * Load data needed by this processor. |
| * |
| * @throws IOException |
| */ |
| protected abstract void loadData() throws IOException; |
| |
| protected void printHeader(PrintWriter pw) { |
| printJavaHeader(pw); |
| } |
| |
| protected void printJavaHeader(PrintWriter pw) { |
| int year = Calendar.getInstance().get(Calendar.YEAR); |
| pw.println("/*"); |
| pw.println(" * Copyright " + year + " Google Inc."); |
| pw.println(" * "); |
| pw.println(" * Licensed under the Apache License, Version 2.0 (the " |
| + "\"License\"); you may not"); |
| pw.println(" * use this file except in compliance with the License. You " |
| + "may obtain a copy of"); |
| pw.println(" * the License at"); |
| pw.println(" * "); |
| pw.println(" * http://www.apache.org/licenses/LICENSE-2.0"); |
| pw.println(" * "); |
| pw.println(" * Unless required by applicable law or agreed to in writing, " + "software"); |
| pw.println(" * distributed under the License is distributed on an \"AS " |
| + "IS\" BASIS, WITHOUT"); |
| pw.println(" * WARRANTIES OR CONDITIONS OF ANY KIND, either express or " + "implied. See the"); |
| pw.println(" * License for the specific language governing permissions and " |
| + "limitations under"); |
| pw.println(" * the License."); |
| pw.println(" */"); |
| } |
| |
| protected void printPropertiesHeader(PrintWriter pw) { |
| int year = Calendar.getInstance().get(Calendar.YEAR); |
| pw.println("# Copyright " + year + " Google Inc."); |
| pw.println("# "); |
| pw.println("# Licensed under the Apache License, Version 2.0 (the " |
| + "\"License\"); you may not"); |
| pw.println("# use this file except in compliance with the License. You " |
| + "may obtain a copy of"); |
| pw.println("# the License at"); |
| pw.println("# "); |
| pw.println("# http://www.apache.org/licenses/LICENSE-2.0"); |
| pw.println("# "); |
| pw.println("# Unless required by applicable law or agreed to in writing, " + "software"); |
| pw.println("# distributed under the License is distributed on an \"AS " |
| + "IS\" BASIS, WITHOUT"); |
| pw.println("# WARRANTIES OR CONDITIONS OF ANY KIND, either express or " + "implied. See the"); |
| pw.println("# License for the specific language governing permissions and " |
| + "limitations under"); |
| pw.println("# the License."); |
| } |
| |
| protected void printVersion(PrintWriter pw, GwtLocale locale, String prefix) { |
| pw.println(prefix + "DO NOT EDIT - GENERATED FROM CLDR DATA:"); |
| Map<String, String> map = localeData.getEntries("version", locale); |
| for (Map.Entry<String, String> entry : map.entrySet()) { |
| pw.println(prefix + " " + entry.getKey() + "=" + entry.getValue()); |
| } |
| pw.println(); |
| } |
| |
| /** |
| * Set whether method definitions should use @Override. |
| * |
| * @param useOverride |
| */ |
| protected void setOverrides(boolean useOverride) { |
| this.useOverride = useOverride; |
| } |
| |
| /** |
| * Write output files produced by this processor. |
| * |
| * @throws IOException |
| */ |
| protected abstract void writeOutputFiles() throws IOException; |
| } |