1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.incubator.jpackage.internal; 27 28 import java.io.IOException; 29 import java.nio.file.Files; 30 import java.nio.file.Path; 31 import java.util.Map; 32 import java.util.Objects; 33 import java.util.Optional; 34 import static jdk.incubator.jpackage.internal.OverridableResource.createResource; 35 import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; 36 import static jdk.incubator.jpackage.internal.StandardBundlerParam.CONFIG_ROOT; 37 38 /** 39 * Runs custom script from resource directory. 40 */ 41 class ScriptRunner { ScriptRunner()42 ScriptRunner() { 43 environment = new ProcessBuilder().environment(); 44 } 45 setResourceCategoryId(String v)46 ScriptRunner setResourceCategoryId(String v) { 47 resourceCategoryId = v; 48 return this; 49 } 50 setDirectory(Path v)51 ScriptRunner setDirectory(Path v) { 52 directory = v; 53 return this; 54 } 55 setScriptNameSuffix(String v)56 ScriptRunner setScriptNameSuffix(String v) { 57 scriptNameSuffix = v; 58 return this; 59 } 60 addEnvironment(Map<String, String> v)61 ScriptRunner addEnvironment(Map<String, String> v) { 62 environment.putAll(v); 63 return this; 64 } 65 setEnvironmentVariable(String envVarName, String envVarValue)66 ScriptRunner setEnvironmentVariable(String envVarName, String envVarValue) { 67 Objects.requireNonNull(envVarName); 68 if (envVarValue == null) { 69 environment.remove(envVarName); 70 } else { 71 environment.put(envVarName, envVarValue); 72 } 73 return this; 74 } 75 run(Map<String, ? super Object> params)76 public void run(Map<String, ? super Object> params) throws IOException { 77 String scriptName = String.format("%s-%s%s", APP_NAME.fetchFrom(params), 78 scriptNameSuffix, scriptSuffix()); 79 Path scriptPath = CONFIG_ROOT.fetchFrom(params).toPath().resolve( 80 scriptName); 81 createResource(null, params) 82 .setCategory(I18N.getString(resourceCategoryId)) 83 .saveToFile(scriptPath); 84 if (!Files.exists(scriptPath)) { 85 return; 86 } 87 88 ProcessBuilder pb = new ProcessBuilder(shell(), 89 scriptPath.toAbsolutePath().toString()); 90 Map<String, String> workEnvironment = pb.environment(); 91 workEnvironment.clear(); 92 workEnvironment.putAll(environment); 93 94 if (directory != null) { 95 pb.directory(directory.toFile()); 96 } 97 98 Executor.of(pb).executeExpectSuccess(); 99 } 100 shell()101 private static String shell() { 102 if (Platform.isWindows()) { 103 return "cscript"; 104 } 105 return Optional.ofNullable(System.getenv("SHELL")).orElseGet(() -> "sh"); 106 } 107 scriptSuffix()108 private static String scriptSuffix() { 109 if (Platform.isWindows()) { 110 return ".wsf"; 111 } 112 return ".sh"; 113 } 114 115 private String scriptNameSuffix; 116 private String resourceCategoryId; 117 private Path directory; 118 private Map<String, String> environment; 119 } 120