From e0ef7b1b06c2fe7d527e86dd7cf2aa0e075e4d3d Mon Sep 17 00:00:00 2001 From: Colin Alworth Date: Wed, 8 Jan 2025 20:40:09 -0600 Subject: [PATCH] Extract remaining i18n/webapp creator calls to a new type --- .../gwt/core/ext/linker/LinkerUtils.java | 1 - dev/core/src/com/google/gwt/dev/GWTMain.java | 8 +- .../src/com/google/gwt/dev/util/Util.java | 1 + .../google/gwt/i18n/tools/I18NCreator.java | 28 +-- .../user/tools/CommandLineCreatorUtils.java | 210 ++++++++++++++++++ .../google/gwt/user/tools/WebAppCreator.java | 13 +- 6 files changed, 232 insertions(+), 29 deletions(-) create mode 100644 user/src/com/google/gwt/user/tools/CommandLineCreatorUtils.java diff --git a/dev/core/src/com/google/gwt/core/ext/linker/LinkerUtils.java b/dev/core/src/com/google/gwt/core/ext/linker/LinkerUtils.java index 2252b163bf6..965c9026dce 100644 --- a/dev/core/src/com/google/gwt/core/ext/linker/LinkerUtils.java +++ b/dev/core/src/com/google/gwt/core/ext/linker/LinkerUtils.java @@ -13,7 +13,6 @@ * License for the specific language governing permissions and limitations under * the License. */ - package com.google.gwt.core.ext.linker; import java.io.FileNotFoundException; diff --git a/dev/core/src/com/google/gwt/dev/GWTMain.java b/dev/core/src/com/google/gwt/dev/GWTMain.java index 2e292c3483c..90d3ae07ab2 100644 --- a/dev/core/src/com/google/gwt/dev/GWTMain.java +++ b/dev/core/src/com/google/gwt/dev/GWTMain.java @@ -15,7 +15,6 @@ */ package com.google.gwt.dev; -import com.google.gwt.dev.util.Util; import com.google.gwt.thirdparty.guava.common.base.Strings; /** @@ -25,12 +24,7 @@ public class GWTMain { public static void main(String args[]) { - String aboutText = Util.getFileFromInstallPath("about.txt"); - if (aboutText != null) { - System.err.println(aboutText); - } else { - System.err.println(About.getGwtVersion()); - } + System.err.println(About.getGwtVersion()); System.err.println("Available main classes:"); System.err.println(Strings.padEnd(DevMode.class.getName(), 40, ' ') + "runs the development shell"); diff --git a/dev/core/src/com/google/gwt/dev/util/Util.java b/dev/core/src/com/google/gwt/dev/util/Util.java index da1142c852c..2f639185552 100644 --- a/dev/core/src/com/google/gwt/dev/util/Util.java +++ b/dev/core/src/com/google/gwt/dev/util/Util.java @@ -294,6 +294,7 @@ public static String getClassName(String className) { * * @param relativePath relative path within the install directory * @return the contents of the file, or null if an error occurred + * @deprecated Removed without replacement, many usages of GWT have no install path. */ public static String getFileFromInstallPath(String relativePath) { String installPath = Utility.getInstallPath(); diff --git a/user/src/com/google/gwt/i18n/tools/I18NCreator.java b/user/src/com/google/gwt/i18n/tools/I18NCreator.java index 935f4b47cd7..c1ec8d7aed3 100755 --- a/user/src/com/google/gwt/i18n/tools/I18NCreator.java +++ b/user/src/com/google/gwt/i18n/tools/I18NCreator.java @@ -19,13 +19,13 @@ import com.google.gwt.i18n.client.ConstantsWithLookup; import com.google.gwt.i18n.client.Localizable; import com.google.gwt.i18n.client.Messages; +import com.google.gwt.user.tools.CommandLineCreatorUtils; import com.google.gwt.user.tools.util.ArgHandlerEclipse; import com.google.gwt.user.tools.util.ArgHandlerIgnore; import com.google.gwt.user.tools.util.ArgHandlerOverwrite; import com.google.gwt.util.tools.ArgHandlerExtra; import com.google.gwt.util.tools.ArgHandlerOutDir; import com.google.gwt.util.tools.ToolBase; -import com.google.gwt.util.tools.Utility; import java.io.File; import java.io.IOException; @@ -131,7 +131,7 @@ static void createLocalizable(String fullInterfaceName, File outDir, Class interfaceToCreate) throws IOException { // Figure out the installation directory - String installPath = Utility.getInstallPath(); + String installPath = CommandLineCreatorUtils.getInstallPath(); String gwtUserPath = installPath + '/' + "gwt-user.jar"; String gwtDevPath = installPath + '/' + "gwt-dev.jar"; @@ -163,10 +163,10 @@ static void createLocalizable(String fullInterfaceName, File outDir, // Compute module name and directories // pos = clientPackageName.lastIndexOf('.'); - File clientDir = Utility.getDirectory(outDir, "src", true); + File clientDir = CommandLineCreatorUtils.getDirectory(outDir, "src", true); if (pos >= 0) { String clientPackage = clientPackageName.replace('.', '/'); - clientDir = Utility.getDirectory(clientDir, clientPackage, true); + clientDir = CommandLineCreatorUtils.getDirectory(clientDir, clientPackage, true); } // Create a map of replacements @@ -185,7 +185,7 @@ static void createLocalizable(String fullInterfaceName, File outDir, if (Messages.class == interfaceToCreate) { replacements.put("@createMessages", "-createMessages"); - templateData = Utility.getFileFromClassPath(PACKAGE_PATH + templateData = CommandLineCreatorUtils.getFileFromClassPath(PACKAGE_PATH + "i18nMessages.propertiessrc"); } else { if (ConstantsWithLookup.class == interfaceToCreate) { @@ -199,26 +199,26 @@ static void createLocalizable(String fullInterfaceName, File outDir, } // This same template works for both Constants and ConstantsWithLookup // classes - templateData = Utility.getFileFromClassPath(PACKAGE_PATH + templateData = CommandLineCreatorUtils.getFileFromClassPath(PACKAGE_PATH + "i18nConstants.propertiessrc"); } // Populate the file from the template - File i18nPropertiesFile = Utility.createNormalFile(clientDir, interfaceName + File i18nPropertiesFile = CommandLineCreatorUtils.createNormalFile(clientDir, interfaceName + ".properties", overwrite, ignore); if (i18nPropertiesFile != null && templateData != null) { - Utility.writeTemplateFile(i18nPropertiesFile, templateData, replacements); + CommandLineCreatorUtils.writeTemplateFile(i18nPropertiesFile, templateData, replacements); } if (eclipse != null) { // Create an eclipse localizable creator launch config replacements.put("@projectName", eclipse); - File updateLaunchConfig = Utility.createNormalFile(outDir, interfaceName + File updateLaunchConfig = CommandLineCreatorUtils.createNormalFile(outDir, interfaceName + "-i18n" + ".launch", overwrite, ignore); if (updateLaunchConfig != null) { - String out = Utility.getFileFromClassPath(PACKAGE_PATH + String out = CommandLineCreatorUtils.getFileFromClassPath(PACKAGE_PATH + "I18N-update.launchsrc"); - Utility.writeTemplateFile(updateLaunchConfig, out, replacements); + CommandLineCreatorUtils.writeTemplateFile(updateLaunchConfig, out, replacements); } } @@ -229,12 +229,12 @@ static void createLocalizable(String fullInterfaceName, File outDir, } else { extension = ""; } - File gwti18n = Utility.createNormalFile(outDir, interfaceName + "-i18n" + File gwti18n = CommandLineCreatorUtils.createNormalFile(outDir, interfaceName + "-i18n" + extension, overwrite, ignore); if (gwti18n != null) { - String out = Utility.getFileFromClassPath(PACKAGE_PATH + "gwti18n" + String out = CommandLineCreatorUtils.getFileFromClassPath(PACKAGE_PATH + "gwti18n" + extension + "src"); - Utility.writeTemplateFile(gwti18n, out, replacements); + CommandLineCreatorUtils.writeTemplateFile(gwti18n, out, replacements); if (extension.length() == 0) { Runtime.getRuntime().exec("chmod u+x " + gwti18n.getAbsolutePath()); } diff --git a/user/src/com/google/gwt/user/tools/CommandLineCreatorUtils.java b/user/src/com/google/gwt/user/tools/CommandLineCreatorUtils.java new file mode 100644 index 00000000000..2318d1946bf --- /dev/null +++ b/user/src/com/google/gwt/user/tools/CommandLineCreatorUtils.java @@ -0,0 +1,210 @@ +/* + * Copyright 2025 GWT Project 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.gwt.user.tools; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.LineNumberReader; +import java.io.PrintWriter; +import java.io.StringReader; +import java.net.URI; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * IO and template utility classes for GWT command-line tools. + */ +public class CommandLineCreatorUtils { + + /** + * @param parent Parent directory + * @param fileName New file name + * @param overwrite Is overwriting an existing file allowed? + * @return Handle to the file + * @throws IOException If the file cannot be created, or if the file already + * existed and overwrite was false. + */ + public static File createNormalFile(File parent, String fileName, + boolean overwrite, boolean ignore) throws IOException { + File file = new File(parent, fileName); + if (file.createNewFile()) { + System.out.println("Created file " + file); + return file; + } + + if (!file.exists() || file.isDirectory()) { + throw new IOException(file.getPath() + " : could not create normal file."); + } + + if (ignore) { + System.out.println(file + " already exists; skipping"); + return null; + } + + if (!overwrite) { + throw new IOException( + file.getPath() + + " : already exists; please remove it or use the -overwrite or -ignore option."); + } + + System.out.println("Overwriting existing file " + file); + return file; + } + + /** + * @param dirPath Requested path for the directory. + * @param create Create the directory if it does not already exist? + * @return A {@link File} representing a directory that now exists. + * @throws IOException If the directory is not found and/or cannot be created. + */ + public static File getDirectory(String dirPath, boolean create) + throws IOException { + return getDirectory(null, dirPath, create); + } + + /** + * @param parent Parent directory of the requested directory. + * @param dirName Requested name for the directory. + * @param create Create the directory if it does not already exist? + * @return A {@link File} representing a directory that now exists. + * @throws IOException If the directory is not found and/or cannot be created. + */ + public static File getDirectory(File parent, String dirName, boolean create) + throws IOException { + File dir = new File(parent, dirName); + boolean alreadyExisted = dir.exists(); + + if (create) { + // No need to check mkdirs result because we check for dir.exists() + dir.mkdirs(); + } + + if (!dir.exists() || !dir.isDirectory()) { + if (create) { + throw new IOException(dir.getPath() + " : could not create directory."); + } else { + throw new IOException(dir.getPath() + " : could not find directory."); + } + } + + if (create && !alreadyExisted) { + System.out.println("Created directory " + dir); + } + + return dir; + } + + /** + * Gets the contents of a file from the class path as a String. Note: this + * method is only guaranteed to work for resources in the same class loader + * that contains this {@link CommandLineCreatorUtils} class. + * + * @param partialPath the partial path to the resource on the class path + * @return the contents of the file + * @throws IOException if the file could not be found or an error occurred + * while reading it + */ + public static String getFileFromClassPath(String partialPath) + throws IOException { + try (InputStream in = CommandLineCreatorUtils.class.getClassLoader().getResourceAsStream( + partialPath)) { + if (in == null) { + throw new FileNotFoundException(partialPath); + } + return new String(in.readAllBytes(), StandardCharsets.UTF_8); + } + } + + public static String getInstallPath() { + return InstallPathHolder.INSTALL_PATH; + } + + private static class InstallPathHolder { + private static final String INSTALL_PATH = computeInstallationPath(); + private static String computeInstallationPath() { + try { + String override = System.getProperty("gwt.devjar"); + if (override == null) { + String partialPath = CommandLineCreatorUtils.class.getName().replace('.', '/').concat( + ".class"); + URL url = CommandLineCreatorUtils.class.getClassLoader().getResource(partialPath); + if (url != null && "jar".equals(url.getProtocol())) { + String path = url.toString(); + String jarPath = path.substring(path.indexOf("file:"), + path.lastIndexOf('!')); + File devJarFile = new File(URI.create(jarPath)); + if (!devJarFile.isFile()) { + throw new IOException("Could not find jar file; " + + devJarFile.getCanonicalPath() + + " does not appear to be a valid file"); + } + + String dirPath = jarPath.substring(0, jarPath.lastIndexOf('/') + 1); + File installDirFile = new File(URI.create(dirPath)); + if (!installDirFile.isDirectory()) { + throw new IOException("Could not find installation directory; " + + installDirFile.getCanonicalPath() + + " does not appear to be a valid directory"); + } + + return installDirFile.getCanonicalPath().replace( + File.separatorChar, '/'); + } else { + throw new IOException( + "Cannot determine installation directory; apparently not running from a jar"); + } + } else { + override = override.replace('\\', '/'); + int pos = override.lastIndexOf('/'); + if (pos < 0) { + return ""; + } else { + return override.substring(0, pos); + } + } + } catch (IOException e) { + throw new RuntimeException( + "Installation problem detected, please reinstall GWT", e); + } + } + } + + public static void writeTemplateFile(File file, String contents, + Map replacements) throws IOException { + String replacedContents = contents; + Set> entries = replacements.entrySet(); + for (Iterator> iter = entries.iterator(); iter.hasNext();) { + Map.Entry entry = iter.next(); + String replaceThis = entry.getKey(); + String withThis = entry.getValue(); + withThis = withThis.replaceAll("\\\\", "\\\\\\\\"); + withThis = withThis.replaceAll("\\$", "\\\\\\$"); + replacedContents = replacedContents.replaceAll(replaceThis, withThis); + } + + try (PrintWriter pw = new PrintWriter(file)) { + LineNumberReader lnr = new LineNumberReader(new StringReader(replacedContents)); + for (String line = lnr.readLine(); line != null; line = lnr.readLine()) { + pw.println(line); + } + } + } +} diff --git a/user/src/com/google/gwt/user/tools/WebAppCreator.java b/user/src/com/google/gwt/user/tools/WebAppCreator.java index 23521680f97..4eccf628b36 100644 --- a/user/src/com/google/gwt/user/tools/WebAppCreator.java +++ b/user/src/com/google/gwt/user/tools/WebAppCreator.java @@ -28,7 +28,6 @@ import com.google.gwt.util.tools.ArgHandlerFlag; import com.google.gwt.util.tools.ArgHandlerOutDir; import com.google.gwt.util.tools.ArgHandlerString; -import com.google.gwt.util.tools.Utility; import java.io.File; import java.io.FileOutputStream; @@ -511,7 +510,7 @@ public List getFiles(Map replacements) throws IOException, WebAppCreatorException { List files = new ArrayList(); - Utility.getDirectory(outDir.getPath(), true); + CommandLineCreatorUtils.getDirectory(outDir.getPath(), true); for (String template : templates) { URL templateUrl = getTemplateRoot(template); @@ -724,7 +723,7 @@ protected void doRun(String installPath) throws IOException, WebAppCreatorExcept if (url == null) { throw new WebAppCreatorException("Could not find " + fileCreator.sourceName); } - File file = Utility.createNormalFile(fileCreator.destDir, + File file = CommandLineCreatorUtils.createNormalFile(fileCreator.destDir, fileCreator.destName, overwrite, ignore); if (file == null) { continue; @@ -735,14 +734,14 @@ protected void doRun(String installPath) throws IOException, WebAppCreatorExcept } } else { String data = Util.readURLAsString(url); - Utility.writeTemplateFile(file, data, replacements); + CommandLineCreatorUtils.writeTemplateFile(file, data, replacements); } } } protected boolean run() { try { - doRun(Utility.getInstallPath()); + doRun(CommandLineCreatorUtils.getInstallPath()); return true; } catch (IOException e) { System.err.println(e.getClass().getName() + ": " + e.getMessage()); @@ -764,7 +763,7 @@ private Collection getTemplateFiles( String replacedName = replaceFileName(replacements, srcFile.getName()); if (srcFile.isDirectory()) { - File newDirectory = Utility.getDirectory(destDirectory, replacedName, true); + File newDirectory = CommandLineCreatorUtils.getDirectory(destDirectory, replacedName, true); files.addAll(getTemplateFiles(replacements, srcFile, newDirectory, templateClassRoot + srcFile.getName() + "/")); } else if (srcFile.getName().endsWith("src")) { @@ -813,7 +812,7 @@ private Collection getTemplateFilesFromZip( String relativeName = fullName.substring(templateDirName.length()); String replacedName = replaceFileName(replacements, relativeName); if (entry.isDirectory()) { - Utility.getDirectory(destDirectory, replacedName, true); + CommandLineCreatorUtils.getDirectory(destDirectory, replacedName, true); } else if (fullName.endsWith("src")) { // remove the src suffix String destName = replacedName.substring(0, replacedName.length() - 3);