All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.nativeexecution.api.NativeProcessBuilder Maven / Gradle / Ivy

The newest version!
/*
 * 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.netbeans.modules.nativeexecution.api;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.Callable;
import javax.swing.event.ChangeListener;
import org.netbeans.api.extexecution.ExecutionService;
import org.netbeans.modules.nativeexecution.AbstractNativeProcess;
import org.netbeans.modules.nativeexecution.LocalNativeProcess;
import org.netbeans.modules.nativeexecution.NativeProcessInfo;
import org.netbeans.modules.nativeexecution.NbLocalNativeProcess;
import org.netbeans.modules.nativeexecution.NbRemoteNativeProcess;
import org.netbeans.modules.nativeexecution.PtyNativeProcess;
import org.netbeans.modules.nativeexecution.RemoteNativeProcess;
import org.netbeans.modules.nativeexecution.TerminalLocalNativeProcess;
import org.netbeans.modules.nativeexecution.api.pty.PtySupport;
import org.netbeans.modules.nativeexecution.api.util.ConnectionManager;
import org.netbeans.modules.nativeexecution.api.util.ExternalTerminal;
import org.netbeans.modules.nativeexecution.api.util.ExternalTerminalProvider;
import org.netbeans.modules.nativeexecution.api.util.MacroMap;
import org.netbeans.modules.nativeexecution.api.util.Shell;
import org.netbeans.modules.nativeexecution.api.util.ShellValidationSupport;
import org.netbeans.modules.nativeexecution.api.util.ShellValidationSupport.ShellValidationStatus;
import org.netbeans.modules.nativeexecution.api.util.WindowsSupport;
import org.netbeans.modules.nativeexecution.pty.NbStartUtility;
import org.netbeans.modules.nativeexecution.spi.support.NativeExecutionUserNotification;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.openide.util.RequestProcessor;
import org.openide.util.UserQuestionException;
import org.openide.util.Utilities;

/**
 * Utility class for the {@link NativeProcess external native process} creation.
 * 

* Depending on {@link ExecutionEnvironment} it creates either local process or * remote one. This class was designed to be usable with {@link ExecutionService} * provided by the * External Execution Support * NetBeans module. *

* Builder handles command, working directory, environment, task's listeners and * execution in an external terminal. *

*/ // @NotThreadSafe public final class NativeProcessBuilder implements Callable { private final NativeProcessInfo info; private ExternalTerminal externalTerminal = null; private NativeProcessBuilder(final ExecutionEnvironment execEnv) { info = new NativeProcessInfo(execEnv); } /** * Creates a new instance of the builder that will create a {@link NativeProcess} * in the specified execution environment. * @param execEnv execution environment that defines where a native * process will be started. * @return new instance of process builder */ public static NativeProcessBuilder newProcessBuilder(ExecutionEnvironment execEnv) { return new NativeProcessBuilder(execEnv); } /** * Creates a new instance of the builder that will create a {@link NativeProcess} * on the localhost. * @return new instance of process builder */ public static NativeProcessBuilder newLocalProcessBuilder() { return new NativeProcessBuilder(ExecutionEnvironmentFactory.getLocal()); } public NativeProcessBuilder redirectError() { info.redirectError(true); return this; } public boolean redirectErrorStream() { return info.isRedirectError(); } /** * Specif * @param executable * @return */ public NativeProcessBuilder setExecutable(String executable) { info.setExecutable(executable); return this; } /** * NB! no arguments can be set after that. * command line it not escaped before execution. * @param commandLine * @return */ @SuppressWarnings("deprecation") public NativeProcessBuilder setCommandLine(String commandLine) { info.setCommandLine(commandLine); return this; } /** * Register passed NativeProcess.Listener. * * @param listener NativeProcess.Listener to be registered to receive * process's state change events. * * @return this */ public NativeProcessBuilder addNativeProcessListener(ChangeListener listener) { info.addChangeListener(listener); return this; } public NativeProcessBuilder removeNativeProcessListener(ChangeListener listener) { info.removeChangeListener(listener); return this; } public MacroMap getEnvironment() { return info.getEnvironment(); } /** * Creates a new {@link NativeProcess} based on the properties configured * in this builder. * @return new {@link NativeProcess} based on the properties configured * in this builder * @throws IOException if the process could not be created * @throws UserQuestionException in case the system is not yet connected */ @Messages({ "# {0} - display name of execution environment", "EXC_NotConnectedQuestion=No connection to {0}. Connect now?" }) @Override public NativeProcess call() throws IOException { AbstractNativeProcess process = null; final ExecutionEnvironment execEnv = info.getExecutionEnvironment(); if (info.getCommand() == null) { throw new IllegalStateException("No executable nor command line is specified"); // NOI18N } if (!ConnectionManager.getInstance().isConnectedTo(execEnv)) { throw new UserQuestionException("No connection to " + execEnv.getDisplayName()) {// NOI18N @Override public void confirmed() throws IOException { RequestProcessor.getDefault().post(new Runnable() { @Override public void run() { ConnectionManager.getInstance().connect(execEnv); } }); } @Override public String getLocalizedMessage() { return Bundle.EXC_NotConnectedQuestion(execEnv.getDisplayName()); } }; } if (externalTerminal == null && NbStartUtility.getInstance().isSupported(info.getExecutionEnvironment())) { if (info.getExecutionEnvironment().isLocal()) { process = new NbLocalNativeProcess(info); } else { process = new NbRemoteNativeProcess(info); } } else { if (info.isPtyMode() && PtySupport.isSupportedFor(info.getExecutionEnvironment())) { process = new PtyNativeProcess(info); } else { if (info.getExecutionEnvironment().isRemote()) { process = new RemoteNativeProcess(info); } else { if (externalTerminal != null) { boolean canProceed = true; boolean available = externalTerminal.isAvailable(info.getExecutionEnvironment()); if (!available) { if (Boolean.getBoolean("nativeexecution.mode.unittest") || "true".equals(System.getProperty("cnd.command.line.utility"))) { // NOI18N System.err.println(loc("NativeProcessBuilder.processCreation.NoTermianl.text")); } else { NativeExecutionUserNotification.getDefault().notify(loc("NativeProcessBuilder.processCreation.NoTermianl.text"), // NOI18N NativeExecutionUserNotification.Descriptor.WARNING); // DialogDisplayer.getDefault().notify( // new NotifyDescriptor.Message(loc("NativeProcessBuilder.processCreation.NoTermianl.text"), // NOI18N // NotifyDescriptor.WARNING_MESSAGE)); } canProceed = false; } else { if (Utilities.isWindows()) { Shell shell = WindowsSupport.getInstance().getActiveShell(); if (shell == null) { if (Boolean.getBoolean("nativeexecution.mode.unittest") || "true".equals(System.getProperty("cnd.command.line.utility"))) { // NOI18N System.err.println(loc("NativeProcessBuilder.processCreation.NoShell.text")); } else { NativeExecutionUserNotification.getDefault().notify(loc("NativeProcessBuilder.processCreation.NoShell.text"), // NOI18N NativeExecutionUserNotification.Descriptor.WARNING); // DialogDisplayer.getDefault().notify( // new NotifyDescriptor.Message(loc("NativeProcessBuilder.processCreation.NoShell.text"), // NOI18N // NotifyDescriptor.WARNING_MESSAGE)); } canProceed = false; } else { ShellValidationStatus validationStatus = ShellValidationSupport.getValidationStatus(shell); if (!validationStatus.isValid()) { canProceed = ShellValidationSupport.confirm( loc("NativeProcessBuilder.processCreation.BrokenShellConfirmationHeader.text"), // NOI18N loc("NativeProcessBuilder.processCreation.BrokenShellConfirmationFooter.text"), // NOI18N validationStatus); } } } if (canProceed) { process = new TerminalLocalNativeProcess(info, externalTerminal); } } } } if (process == null) { // Either externalTerminal is null or there are some problems with it process = new LocalNativeProcess(info); } } } return process.createAndStart(); } /** * Configures a working directory. * Process subsequently created by the call() method on this builder * will be executed with this directory as a current working dir. *

* The default value is undefined. *

* @param workingDirectory working directory to start process in. * @return this */ public NativeProcessBuilder setWorkingDirectory(String workingDirectory) { info.setWorkingDirectory(workingDirectory); return this; } /** * Configure arguments of the command. * *

* By default executable is started without any arguments. *

* Previously configured arguments are cleared. *

* If there is a need to parse arguments already provided as one big string * the method that can help is * {@link org.openide.util.Utilitiesies#parseParameters(java.lang.String)}. * * @param arguments command arguments * @return this */ public NativeProcessBuilder setArguments(String... arguments) { info.setArguments(arguments); return this; } /** * Configure external terminal to be used to execute configured process. * *

* @param terminal terminal specification * @return this * * @see ExternalTerminalProvider */ public NativeProcessBuilder useExternalTerminal(/*@NullAllowed*/ExternalTerminal terminal) { externalTerminal = terminal; return this; } /** * Configure whether to use output unbuffering or not. * @param unbuffer - if true, native unbuffer library will be preloaded. * @return this */ public NativeProcessBuilder unbufferOutput(boolean unbuffer) { info.setUnbuffer(unbuffer); return this; } /** * Configure X11 forwarding. * * @param x11forwarding pass true to enable forwarding, * or false to disable * @return this */ public NativeProcessBuilder setX11Forwarding(boolean x11forwarding) { if (Boolean.getBoolean("cnd.remote.noX11")) { return this; // } info.setX11Forwarding(x11forwarding); return this; } /** * Configure whether process starts normally or suspended. * Suspended process can be resumed by sending it SIGCONT signal. * Note that suspended process is also in RUNNING state. * * @param suspend pass true to start process suspended, * or false to start process normally * @return this */ public NativeProcessBuilder setInitialSuspend(boolean suspend) { info.setInitialSuspend(suspend); return this; } private static String loc(String key, String... params) { return NbBundle.getMessage(NativeProcessBuilder.class, key, params); } /** * Configure whether process starts in a prseudo-terminal or not. * * @param usePty - if true, process builder will start the process in * a pty mode * @return this */ public NativeProcessBuilder setUsePty(boolean usePty) { info.setPtyMode(usePty); return this; } /** * Process builder try to expand, escape, quote command line according to subset of shell man. * By default builder do this. This method allows to forbid preprocessing of command line. * * @param expandMacros - if false, process builder do not preprocess command line * @return this */ public NativeProcessBuilder setMacroExpansion(boolean expandMacros) { info.setExpandMacros(expandMacros); return this; } public NativeProcessBuilder setCharset(Charset charset) { info.setCharset(charset); return this; } public NativeProcessBuilder setStatusEx(boolean b) { info.setStatusEx(b); return this; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy