/* * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; /** * @test * @requires release.implementor == "Oracle Corporation" * @modules jdk.jlink/jdk.tools.jimage * @summary Oracle builds of OpenJDK should only contain english, chinese and * japanese translations */ public class VerifyTranslations { /** * The set of translations we want to see in an Oracle built image */ private static final Set VALID_TRANSLATION_SUFFIXES = Set.of( "_en", "_en_US", "_en_US_POSIX", "_ja", "_zh_CN", "_de" ); /** * This regexp will not match locales with 3 letter lang strings because * doing so would trigger a ton of false positives all over the source * tree. This is ok for now but is a potential future flaw in the test. */ private static final String BASE_LOCALE_REGEXP = "(_[a-z]{2}(_[A-Z][a-z]{3})?(_([A-Z]{2})|([0-9]{3}))?(_[a-zA-Z]+)?)"; public static void main(String[] args) { String jdkPath = System.getProperty("test.jdk"); String modulesFile = jdkPath + "/lib/modules"; // Run jimage tool to extract list of all classes and resources in the jdk StringWriter output = new StringWriter(); jdk.tools.jimage.Main.run(new String[] { "list", modulesFile }, new PrintWriter(output)); Pattern classesLocalePattern = Pattern.compile(BASE_LOCALE_REGEXP + "\\.(class|properties)"); boolean failed = false; String module = ""; for (String line : output.toString().split("\n")) { if (line.startsWith("Module: ")) { module = line.substring(8).trim(); } // We do not filter resources in jdk.localedata if (!module.equals("jdk.localedata")) { Matcher matcher = classesLocalePattern.matcher(line); if (matcher.find()) { if (!VALID_TRANSLATION_SUFFIXES.contains(matcher.group(1))) { System.out.println("Unsupported translation found in lib/modules: " + module + "/" + line.trim()); failed = true; } } } } // Check all files in src.zip Pattern sourceLocalePattern = Pattern.compile(BASE_LOCALE_REGEXP + "\\.java"); String srcZip = jdkPath + "/lib/src.zip"; try (ZipInputStream srcZipInput = new ZipInputStream( new BufferedInputStream(new FileInputStream(srcZip)))) { ZipEntry entry; while ((entry = srcZipInput.getNextEntry()) != null) { String name = entry.getName(); if (!name.startsWith("jdk.localedata")) { Matcher matcher = sourceLocalePattern.matcher(name); if (matcher.find()) { if (!VALID_TRANSLATION_SUFFIXES.contains(matcher.group(1))) { System.out.println("Unsupported translation found in lib/src.zip: " + name); failed = true; } } } } } catch (IOException e) { throw new RuntimeException(e); } if (failed) { throw new RuntimeException("lib/modules contains unsupported translations"); } } }