You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2019/08/15 11:19:09 UTC

[tomcat] 02/03: Copy and modify import code from 9.0.x to import i18n back-ports

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 2bffa95a4c5f016f173241a565b7cadefbc85ca5
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Aug 15 11:43:29 2019 +0100

    Copy and modify import code from 9.0.x to import i18n back-ports
---
 .../tomcat/buildutil/translate/Constants.java      |  29 +++++
 .../apache/tomcat/buildutil/translate/Import.java  | 133 +++++++++++++++++++
 .../apache/tomcat/buildutil/translate/Utils.java   | 145 +++++++++++++++++++++
 3 files changed, 307 insertions(+)

diff --git a/java/org/apache/tomcat/buildutil/translate/Constants.java b/java/org/apache/tomcat/buildutil/translate/Constants.java
new file mode 100644
index 0000000..403daa6
--- /dev/null
+++ b/java/org/apache/tomcat/buildutil/translate/Constants.java
@@ -0,0 +1,29 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 org.apache.tomcat.buildutil.translate;
+
+public class Constants {
+
+    public static final String L10N_PREFIX = "LocalStrings";
+    public static final String L10N_SUFFIX = ".properties";
+
+    public static final String[] SEARCH_DIRS = new String[] { "java", "webapps" };
+
+    public static final String STORAGE_DIR = ".settings/translations";
+
+    public static final String END_PACKAGE_MARKER = ".zzz.";
+}
diff --git a/java/org/apache/tomcat/buildutil/translate/Import.java b/java/org/apache/tomcat/buildutil/translate/Import.java
new file mode 100644
index 0000000..f309217
--- /dev/null
+++ b/java/org/apache/tomcat/buildutil/translate/Import.java
@@ -0,0 +1,133 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 org.apache.tomcat.buildutil.translate;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Properties;
+
+public class Import {
+
+    public static void main(String... args) throws IOException {
+        File root = new File(Constants.STORAGE_DIR);
+
+        for (File f : root.listFiles()) {
+            // Not robust but good enough
+            if (f.isFile() && f.getName().startsWith(Constants.L10N_PREFIX)) {
+                processFile(f);
+            }
+        }
+    }
+
+
+    @SuppressWarnings("null")
+    private static void processFile(File f) throws IOException {
+        String language = Utils.getLanguage(f.getName());
+
+        // Unlike the master branch, don't skip the original so we can import
+        // updates to the English translations
+        Properties props = Utils.load(f);
+        Object[] objKeys = props.keySet().toArray();
+        Arrays.sort(objKeys);
+
+        String currentPkg = null;
+        Writer w = null;
+        String currentGroup = "zzz";
+
+        for (Object objKey : objKeys) {
+            String key = (String) objKey;
+            CompositeKey cKey = new CompositeKey(key);
+
+            if (!cKey.pkg.equals(currentPkg)) {
+                currentPkg = cKey.pkg;
+                if (w != null) {
+                    w.close();
+                }
+                File outFile = new File(currentPkg.replace('.', File.separatorChar), Constants.L10N_PREFIX + language + Constants.L10N_SUFFIX);
+                FileOutputStream fos = new FileOutputStream(outFile);
+                w = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
+                insertLicense(w);
+            }
+
+            if (!currentGroup.equals(cKey.group)) {
+                currentGroup = cKey.group;
+                w.write(System.lineSeparator());
+            }
+
+            w.write(cKey.key + "=" + Utils.formatValue(props.getProperty(key)));
+            w.write(System.lineSeparator());
+        }
+        if (w != null) {
+            w.close();
+        }
+    }
+
+
+    private static void insertLicense(Writer w) throws IOException {
+        w.write("# Licensed to the Apache Software Foundation (ASF) under one or more");
+        w.write(System.lineSeparator());
+        w.write("# contributor license agreements.  See the NOTICE file distributed with");
+        w.write(System.lineSeparator());
+        w.write("# this work for additional information regarding copyright ownership.");
+        w.write(System.lineSeparator());
+        w.write("# The ASF licenses this file to You under the Apache License, Version 2.0");
+        w.write(System.lineSeparator());
+        w.write("# (the \"License\"); you may not use this file except in compliance with");
+        w.write(System.lineSeparator());
+        w.write("# the License.  You may obtain a copy of the License at");
+        w.write(System.lineSeparator());
+        w.write("#");
+        w.write(System.lineSeparator());
+        w.write("#     http://www.apache.org/licenses/LICENSE-2.0");
+        w.write(System.lineSeparator());
+        w.write("#");
+        w.write(System.lineSeparator());
+        w.write("# Unless required by applicable law or agreed to in writing, software");
+        w.write(System.lineSeparator());
+        w.write("# distributed under the License is distributed on an \"AS IS\" BASIS,");
+        w.write(System.lineSeparator());
+        w.write("# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.");
+        w.write(System.lineSeparator());
+        w.write("# See the License for the specific language governing permissions and");
+        w.write(System.lineSeparator());
+        w.write("# limitations under the License.");
+        w.write(System.lineSeparator());
+    }
+    private static class CompositeKey {
+
+        public final String pkg;
+        public final String key;
+        public final String group;
+
+        public CompositeKey(String in) {
+            int posPkg = in.indexOf(Constants.END_PACKAGE_MARKER);
+            pkg = in.substring(0, posPkg);
+            key = in.substring(posPkg + Constants.END_PACKAGE_MARKER.length());
+            int posGroup = key.indexOf('.');
+            if (posGroup == -1) {
+                group = "";
+            } else {
+                group = key.substring(0, posGroup);
+            }
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/buildutil/translate/Utils.java b/java/org/apache/tomcat/buildutil/translate/Utils.java
new file mode 100644
index 0000000..8b69c79
--- /dev/null
+++ b/java/org/apache/tomcat/buildutil/translate/Utils.java
@@ -0,0 +1,145 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 org.apache.tomcat.buildutil.translate;
+
+import java.io.File;
+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.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+public class Utils {
+
+    private static final Pattern ADD_CONTINUATION = Pattern.compile("\\n", Pattern.MULTILINE);
+    private static final Pattern ESCAPE_LEADING_SPACE = Pattern.compile("^(\\s)", Pattern.MULTILINE);
+    private static final Pattern FIX_SINGLE_QUOTE = Pattern.compile("(?<!')'(?!')", Pattern.MULTILINE);
+
+    private Utils() {
+        // Utility class. Hide default constructor.
+    }
+
+
+    static String getLanguage(String name) {
+        return name.substring(Constants.L10N_PREFIX.length(), name.length() - Constants.L10N_SUFFIX.length());
+    }
+
+
+    static Properties load(File f) {
+        Properties props = new Properties();
+
+        try (FileInputStream fis = new FileInputStream(f);
+                Reader r = new InputStreamReader(fis, StandardCharsets.UTF_8)) {
+            props.load(r);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return props;
+    }
+
+
+    static String formatValue(String in) {
+        String result = ADD_CONTINUATION.matcher(in).replaceAll("\\\\n\\\\\n");
+        if (result.endsWith("\\\n")) {
+            result = result.substring(0, result.length() - 2);
+        }
+        result = ESCAPE_LEADING_SPACE.matcher(result).replaceAll("\\\\$1");
+
+        if (result.contains("\n\\\t")) {
+            result = result.replace("\n\\\t", "\n\\t");
+        }
+
+        if (result.contains("[{0}]")) {
+            result = FIX_SINGLE_QUOTE.matcher(result).replaceAll("''");
+        }
+        return result;
+    }
+
+
+    static void processDirectory(File root, File dir, Map<String,Properties> translations) throws IOException {
+        for (File f : dir.listFiles()) {
+            if (f.isDirectory()) {
+                processDirectory(root, f, translations);
+            } else if (f.isFile()) {
+                processFile(root, f, translations);
+            }
+        }
+    }
+
+
+    static void processFile(File root, File f, Map<String,Properties> translations) throws IOException {
+        String name = f.getName();
+
+        // non-l10n files
+        if (!name.startsWith(Constants.L10N_PREFIX)) {
+            return;
+        }
+
+        // Determine language
+        String language = Utils.getLanguage(name);
+
+        String keyPrefix = getKeyPrefix(root, f);
+        Properties props = Utils.load(f);
+
+        // Create a Map for the language if one does not exist.
+        Properties translation = translations.get(language);
+        if (translation == null) {
+            translation = new Properties();
+            translations.put(language, translation);
+        }
+
+        // Add the properties from this file to the combined file, prefixing the
+        // key with the package name to ensure uniqueness.
+        for (Object obj : props.keySet()) {
+            String key = (String) obj;
+            String value = props.getProperty(key);
+
+            translation.put(keyPrefix + key, value);
+        }
+    }
+
+
+    static String getKeyPrefix(File root, File f) throws IOException {
+        String prefix = f.getParentFile().getCanonicalPath();
+        prefix = prefix.substring(root.getCanonicalPath().length() + 1);
+        prefix = prefix.replace(File.separatorChar, '.');
+        prefix = prefix + Constants.END_PACKAGE_MARKER;
+        return prefix;
+    }
+
+
+    static void export(String language, Properties translation, File storageDir) {
+        File out = new File(storageDir, Constants.L10N_PREFIX + language + Constants.L10N_SUFFIX);
+        try (FileOutputStream fos = new FileOutputStream(out);
+                Writer w = new OutputStreamWriter(fos, StandardCharsets.UTF_8)) {
+            String[] keys = translation.keySet().toArray(new String[0]);
+            Arrays.sort(keys);
+            for (Object key : keys) {
+                w.write(key + "=" + Utils.formatValue(translation.getProperty((String) key)) + "\n");
+            }
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+        }
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org