/* * 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.tools.ant.taskdefs.launcher; import static org.apache.tools.ant.MagicNames.ANT_SHELL_LAUNCHER_REF_ID; import static org.apache.tools.ant.MagicNames.ANT_VM_LAUNCHER_REF_ID; import java.io.File; import java.io.IOException; import java.util.Optional; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.condition.Os; import org.apache.tools.ant.types.Commandline; import org.apache.tools.ant.util.FileUtils; /** * A command launcher for a particular JVM/OS platform. This class is * a general purpose command launcher which can only launch commands * in the current working directory. */ public class CommandLauncher { protected static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); private static CommandLauncher vmLauncher = null; private static CommandLauncher shellLauncher = null; static { if (!Os.isFamily("os/2")) { vmLauncher = new Java13CommandLauncher(); } if (Os.isFamily("mac") && !Os.isFamily("unix")) { // Mac shellLauncher = new MacCommandLauncher(new CommandLauncher()); } else if (Os.isFamily("os/2")) { // OS/2 shellLauncher = new OS2CommandLauncher(new CommandLauncher()); } else if (Os.isFamily("windows")) { CommandLauncher baseLauncher = new CommandLauncher(); if (!Os.isFamily("win9x")) { // Windows XP/2000/NT shellLauncher = new WinNTCommandLauncher(baseLauncher); } else { // Windows 98/95 - need to use an auxiliary script shellLauncher = new ScriptCommandLauncher("bin/antRun.bat", baseLauncher); } } else if (Os.isFamily("netware")) { CommandLauncher baseLauncher = new CommandLauncher(); shellLauncher = new PerlScriptCommandLauncher("bin/antRun.pl", baseLauncher); } else if (Os.isFamily("openvms")) { // OpenVMS shellLauncher = new VmsCommandLauncher(); } else { // Generic shellLauncher = new ScriptCommandLauncher("bin/antRun", new CommandLauncher()); } } /** * Launches the given command in a new process. * * @param project * The project that the command is part of. * @param cmd * The command to execute. * @param env * The environment for the new process. If null, the * environment of the current process is used. * @return the created Process. * @throws IOException * if attempting to run a command in a specific directory. */ public Process exec(Project project, String[] cmd, String[] env) throws IOException { if (project != null) { project.log("Execute:CommandLauncher: " + Commandline.describeCommand(cmd), Project.MSG_DEBUG); } return Runtime.getRuntime().exec(cmd, env); } /** * Launches the given command in a new process, in the given * working directory. * * @param project * The project that the command is part of. * @param cmd * The command to execute. * @param env * The environment for the new process. If null, the * environment of the current process is used. * @param workingDir * The directory to start the command in. If null, the * current directory is used. * @return the created Process. * @throws IOException * if trying to change directory. */ public Process exec(Project project, String[] cmd, String[] env, File workingDir) throws IOException { if (workingDir == null) { return exec(project, cmd, env); } throw new IOException( "Cannot execute a process in different directory under this JVM"); } /** * Obtains the shell launcher configured for the given project or * the default shell launcher. */ public static CommandLauncher getShellLauncher(Project project) { CommandLauncher launcher = extractLauncher(ANT_SHELL_LAUNCHER_REF_ID, project); if (launcher == null) { launcher = shellLauncher; } return launcher; } /** * Obtains the VM launcher configured for the given project or * the default VM launcher. */ public static CommandLauncher getVMLauncher(Project project) { CommandLauncher launcher = extractLauncher(ANT_VM_LAUNCHER_REF_ID, project); if (launcher == null) { launcher = vmLauncher; } return launcher; } private static CommandLauncher extractLauncher(String referenceName, Project project) { return Optional.ofNullable(project) .map(p -> p.<CommandLauncher> getReference(referenceName)) .orElseGet(() -> getSystemLauncher(referenceName)); } private static CommandLauncher getSystemLauncher(String launcherRefId) { String launcherClass = System.getProperty(launcherRefId); if (launcherClass != null) { try { return Class.forName(launcherClass) .asSubclass(CommandLauncher.class).newInstance(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { System.err.println("Could not instantiate launcher class " + launcherClass + ": " + e.getMessage()); } } return null; } /** * Sets the VM launcher to use for the given project. */ public static void setVMLauncher(Project project, CommandLauncher launcher) { if (project != null) { project.addReference(ANT_VM_LAUNCHER_REF_ID, launcher); } } /** * Sets the shell launcher to use for the given project. */ public static void setShellLauncher(Project project, CommandLauncher launcher) { if (project != null) { project.addReference(ANT_SHELL_LAUNCHER_REF_ID, launcher); } } }