diff -r f60f09aecc4f extexecution/apichanges.xml
--- a/extexecution/apichanges.xml Mon Nov 14 16:01:42 2011 +0100
+++ b/extexecution/apichanges.xml Mon Nov 14 19:03:18 2011 +0100
@@ -105,6 +105,7 @@
External Execution Input API
External Execution Input Printing API
External Execution Process Destroy SPI
+ External Execution SPI
@@ -114,6 +115,22 @@
+ New API/SPI to abstract process builder
+
+
+
+
+
+ New API/SPI classes to allow different implementations
+ of process builders.
+
+
+
+
+
+
+
+
New API method to avoid reset of custom IO
diff -r f60f09aecc4f extexecution/arch.xml
--- a/extexecution/arch.xml Mon Nov 14 16:01:42 2011 +0100
+++ b/extexecution/arch.xml Mon Nov 14 19:03:18 2011 +0100
@@ -51,7 +51,8 @@
that contains support for execution of external processes in the IDE. It also
provide support class for the actual creation of the external process
- and support for destroying the process tree.
+ and support for destroying the process tree. There is also abstraction of
+ process builder.
There is also SPI allowing to register support for destroying the process tree
.
@@ -205,6 +211,21 @@
Client wants to destroy the process, trying to kill whole process tree.
diff -r f60f09aecc4f extexecution/manifest.mf
--- a/extexecution/manifest.mf Mon Nov 14 16:01:42 2011 +0100
+++ b/extexecution/manifest.mf Mon Nov 14 19:03:18 2011 +0100
@@ -2,5 +2,5 @@
AutoUpdate-Show-In-Client: false
OpenIDE-Module: org.netbeans.modules.extexecution/2
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/extexecution/resources/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.27
+OpenIDE-Module-Specification-Version: 1.28
diff -r f60f09aecc4f extexecution/nbproject/project.xml
--- a/extexecution/nbproject/project.xml Mon Nov 14 16:01:42 2011 +0100
+++ b/extexecution/nbproject/project.xml Mon Nov 14 19:03:18 2011 +0100
@@ -130,6 +130,7 @@
org.netbeans.api.extexecution
org.netbeans.api.extexecution.print
org.netbeans.api.extexecution.input
+ org.netbeans.spi.extexecution
org.netbeans.spi.extexecution.destroy
diff -r f60f09aecc4f extexecution/src/org/netbeans/api/extexecution/Bundle.properties
--- a/extexecution/src/org/netbeans/api/extexecution/Bundle.properties Mon Nov 14 16:01:42 2011 +0100
+++ b/extexecution/src/org/netbeans/api/extexecution/Bundle.properties Mon Nov 14 19:03:18 2011 +0100
@@ -41,3 +41,4 @@
# made subject to such option by the copyright holder.
Running=Running
+LocalProcessFactory=Factory creating local processes
diff -r f60f09aecc4f extexecution/src/org/netbeans/api/extexecution/ExternalProcessBuilder.java
--- a/extexecution/src/org/netbeans/api/extexecution/ExternalProcessBuilder.java Mon Nov 14 16:01:42 2011 +0100
+++ b/extexecution/src/org/netbeans/api/extexecution/ExternalProcessBuilder.java Mon Nov 14 19:03:18 2011 +0100
@@ -64,11 +64,13 @@
import org.openide.util.Utilities;
/**
- * Utility class to make the external process creation easier.
+ * Utility class to make the local external process creation easier.
*
* Builder handle command, working directory, PATH
variable and HTTP proxy.
*
* This class is immutable.
+ *
+ * Also see {@link ProcessBuilder#getLocal()}.
*
* @author Petr Hejl
* @see #call()
@@ -278,7 +280,7 @@
List args = buildArguments();
commandList.addAll(args);
- ProcessBuilder pb = new ProcessBuilder(commandList.toArray(new String[commandList.size()]));
+ java.lang.ProcessBuilder pb = new java.lang.ProcessBuilder(commandList.toArray(new String[commandList.size()]));
if (workingDirectory != null) {
pb.directory(workingDirectory);
}
@@ -301,7 +303,7 @@
* @param pb the ProcessBuilder to log.
* @param level the level for logging.
*/
- private void logProcess(final Level level, final ProcessBuilder pb) {
+ private void logProcess(final Level level, final java.lang.ProcessBuilder pb) {
if (!LOGGER.isLoggable(level)) {
return;
@@ -406,7 +408,7 @@
return sb.toString();
}
- private void adjustProxy(ProcessBuilder pb) {
+ private void adjustProxy(java.lang.ProcessBuilder pb) {
String proxy = getNetBeansHttpProxy();
if (proxy != null) {
Map env = pb.environment();
diff -r f60f09aecc4f extexecution/src/org/netbeans/api/extexecution/ProcessBuilder.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extexecution/src/org/netbeans/api/extexecution/ProcessBuilder.java Mon Nov 14 19:03:18 2011 +0100
@@ -0,0 +1,290 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.api.extexecution;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import org.netbeans.api.annotations.common.NonNull;
+import org.netbeans.api.annotations.common.NullAllowed;
+import org.netbeans.spi.extexecution.ProcessBuilderFactory;
+import org.netbeans.spi.extexecution.ProcessBuilderImplementation;
+import org.openide.util.NbBundle;
+import org.openide.util.Parameters;
+
+/**
+ * Abstraction of process builders. You can freely configure the parameters
+ * and then create a process by calling the {@link #call()} method. You can
+ * also (re)configure the builder and spawn a different process.
+ *
+ * Note the API does not prescribe the actual meaning of {@link Process}.
+ * It may be local process, remote process or some other implementation.
+ *
+ * You can use the default implementation returned by {@link #getLocal()}
+ * for creating the local machine OS processes.
+ *
+ * Thread safety of this class depends on thread safety of
+ * the {@link ProcessBuilderImplementation} the class is using. If it is thread
+ * safe (if possible the implementation should be even stateless) this class
+ * is thread safe as well.
+ *
+ * @author Petr Hejl
+ * @since 1.28
+ */
+public final class ProcessBuilder implements Callable {
+
+ private final ProcessBuilderImplementation implementation;
+
+ private final String description;
+
+ /**GuardedBy("this")*/
+ private String executable;
+
+ /**GuardedBy("this")*/
+ private String workingDirectory;
+
+ /**GuardedBy("this")*/
+ private List arguments = new ArrayList();
+
+ /**GuardedBy("this")*/
+ private List paths = new ArrayList();
+
+ /**GuardedBy("this")*/
+ private Map envVariables = new HashMap();
+
+ /**GuardedBy("this")*/
+ private boolean redirectErrorStream;
+
+ static {
+ ProcessBuilderFactory.Accessor.DEFAULT = new ProcessBuilderFactory.Accessor() {
+
+ @Override
+ public ProcessBuilder createProcessBuilder(ProcessBuilderImplementation impl, String description) {
+ return new ProcessBuilder(impl, description);
+ }
+ };
+ }
+
+ private ProcessBuilder(ProcessBuilderImplementation implementation, String description) {
+ this.implementation = implementation;
+ this.description = description;
+ }
+
+ /**
+ * Returns the {@link ProcessBuilder} creating the OS process on local
+ * machine. Returned implementation is thread safe
.
+ *
+ * @return the {@link ProcessBuilder} creating the OS process on local
+ * machine
+ */
+ public static ProcessBuilder getLocal() {
+ return new ProcessBuilder(new LocalProcessFactory(),
+ NbBundle.getMessage(ProcessBuilder.class, "LocalProcessFactory"));
+ }
+
+ /**
+ * Returns the human readable description of this builder.
+ *
+ * @return the human readable description of this builder
+ */
+ @NonNull
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Sets the executable to run. There is no default value. The {@link #call()}
+ * methods throws {@link IllegalStateException} when there is no executable
+ * configured.
+ *
+ * @param executable the executable to run
+ */
+ public void setExecutable(@NonNull String executable) {
+ Parameters.notNull("executable", executable);
+
+ synchronized (this) {
+ this.executable = executable;
+ }
+ }
+
+ /**
+ * Sets the working directory for the process created by subsequent call
+ * of {@link #call()}. The default value is implementation specific.
+ *
+ * @param workingDirectory the working directory of the process
+ */
+ public void setWorkingDirectory(@NullAllowed String workingDirectory) {
+ synchronized (this) {
+ this.workingDirectory = workingDirectory;
+ }
+ }
+
+ /**
+ * Sets the arguments passed to the process created by subsequent call
+ * of {@link #call()}. By default there are no arguments.
+ *
+ * @param arguments the arguments passed to the process
+ */
+ public void setArguments(@NonNull List arguments) {
+ Parameters.notNull("arguments", arguments);
+
+ synchronized (this) {
+ this.arguments.clear();
+ this.arguments.addAll(arguments);
+ }
+ }
+
+ /**
+ * Sets the environment variables for the process created by subsequent call
+ * of {@link #call()}. By default there are no environment variables with
+ * exception of PATH
possibly configured by {@link #setPaths(java.util.List)}.
+ *
+ * @param envVariables the environment variables for the process
+ */
+ public void setEnvironmentVariables(@NonNull Map envVariables) {
+ Parameters.notNull("envVariables", envVariables);
+
+ synchronized (this) {
+ this.envVariables.clear();
+ this.envVariables.putAll(envVariables);
+ }
+ }
+
+ /**
+ * Sets the additional paths to be included in PATH
environment
+ * variable for the process.
+ *
+ * @param paths the additional paths to be included in PATH
+ * environment variable
+ */
+ public void setPaths(@NonNull List paths) {
+ Parameters.notNull("paths", paths);
+
+ synchronized (this) {
+ this.paths.clear();
+ this.paths.addAll(paths);
+ }
+ }
+
+ /**
+ * Configures the error stream redirection. If true
the error
+ * stream of process created by subsequent call of {@link #call()} method
+ * will be redirected to standard output stream.
+ *
+ * @param redirectErrorStream the error stream redirection
+ */
+ public void setRedirectErrorStream(boolean redirectErrorStream) {
+ synchronized (this) {
+ this.redirectErrorStream = redirectErrorStream;
+ }
+ }
+
+ /**
+ * Creates the new {@link Process} based on the properties configured
+ * in this builder.
+ *
+ * Actual behavior depends on the builder implementation, but it should
+ * respect all the properties configured on this builder.
+ *
+ * @see ProcessBuilderImplementation
+ * @return the new {@link Process} based on the properties configured
+ * in this builder
+ * @throws IOException if the process could not be created
+ * @throws IllegalStateException if there is no executable configured
+ * by {@link #setExecutable(java.lang.String)}
+ */
+ @NonNull
+ @Override
+ public Process call() throws IOException {
+ String currentExecutable = null;
+ String currentWorkingDirectory = null;
+ List currentArguments = new ArrayList();
+ List currentPaths = new ArrayList();
+ Map currentEnvVariables = new HashMap();
+ boolean currentRedirectErrorStream = false;
+
+ synchronized (this) {
+ currentExecutable = executable;
+ currentWorkingDirectory = workingDirectory;
+ currentArguments.addAll(arguments);
+ currentPaths.addAll(paths);
+ currentEnvVariables.putAll(envVariables);
+ currentRedirectErrorStream = redirectErrorStream;
+ }
+
+ if (currentExecutable == null) {
+ throw new IllegalStateException("The executable has not been configured");
+ }
+
+ return implementation.createProcess(currentExecutable, currentWorkingDirectory, currentArguments,
+ currentPaths, currentEnvVariables, currentRedirectErrorStream);
+ }
+
+ private static class LocalProcessFactory implements ProcessBuilderImplementation {
+
+ @Override
+ public Process createProcess(String executable, String workingDirectory, List arguments,
+ List paths, Map environment, boolean redirectErrorStream) throws IOException {
+
+ ExternalProcessBuilder builder = new ExternalProcessBuilder(executable);
+ if (workingDirectory != null) {
+ builder = builder.workingDirectory(new File(workingDirectory));
+ }
+ for (String argument : arguments) {
+ builder = builder.addArgument(argument);
+ }
+ for (String path : paths) {
+ builder = builder.prependPath(new File(path));
+ }
+ for (Map.Entry entry : environment.entrySet()) {
+ builder = builder.addEnvironmentVariable(entry.getKey(), entry.getValue());
+ }
+ builder = builder.redirectErrorStream(redirectErrorStream);
+
+ return builder.call();
+ }
+ }
+}
diff -r f60f09aecc4f extexecution/src/org/netbeans/spi/extexecution/ProcessBuilderFactory.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extexecution/src/org/netbeans/spi/extexecution/ProcessBuilderFactory.java Mon Nov 14 19:03:18 2011 +0100
@@ -0,0 +1,101 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.spi.extexecution;
+
+/**
+ * The factory allowing SPI implementors of {@link ProcessBuilderImplementation}
+ * to create its API instances {@link org.netbeans.api.extexecution.ProcessBuilder}.
+ *
+ * @author Petr Hejl
+ * @since 1.28
+ */
+public class ProcessBuilderFactory {
+
+ private ProcessBuilderFactory() {
+ super();
+ }
+
+ /**
+ * Creates the instance of {@link org.netbeans.api.extexecution.ProcessBuilder}
+ * from its SPI representation.
+ *
+ * @param impl SPI representation
+ * @param description human readable description of the builder
+ * @return the API instance
+ */
+ public static org.netbeans.api.extexecution.ProcessBuilder createProcessBuilder(
+ ProcessBuilderImplementation impl, String description) {
+ return Accessor.DEFAULT.createProcessBuilder(impl, description);
+ }
+
+ /**
+ * The accessor pattern class.
+ */
+ public abstract static class Accessor {
+
+ /** The default accessor. */
+ public static Accessor DEFAULT;
+
+ static {
+ // invokes static initializer of ProcessBuilder.class
+ // that will assign value to the DEFAULT field above
+ Class c = org.netbeans.api.extexecution.ProcessBuilder.class;
+ try {
+ Class.forName(c.getName(), true, c.getClassLoader());
+ } catch (ClassNotFoundException ex) {
+ assert false : ex;
+ }
+ }
+
+ /**
+ * Creates the instance of {@link org.netbeans.api.extexecution.ProcessBuilder}
+ * from its SPI representation.
+ *
+ * @param impl SPI representation
+ * @param description human readable description of the builder
+ * @return the API instance
+ */
+ public abstract org.netbeans.api.extexecution.ProcessBuilder createProcessBuilder(
+ ProcessBuilderImplementation impl, String description);
+
+ }
+}
diff -r f60f09aecc4f extexecution/src/org/netbeans/spi/extexecution/ProcessBuilderImplementation.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extexecution/src/org/netbeans/spi/extexecution/ProcessBuilderImplementation.java Mon Nov 14 19:03:18 2011 +0100
@@ -0,0 +1,88 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.spi.extexecution;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import org.netbeans.api.annotations.common.NonNull;
+import org.netbeans.api.annotations.common.NullAllowed;
+
+/**
+ * The interface representing the implementation
+ * of {@link org.netbeans.api.extexecution.ProcessBuilder}.
+ *
+ *
+ *
+ * Although it is not required it is reasonable to have implementation of this
+ * interface stateless. In such case instances of {@link org.netbeans.api.extexecution.ProcessBuilder}
+ * using it will be thread safe.
+ *
+ *
+ * @see org.netbeans.api.extexecution.ProcessBuilder
+ * @author Petr Hejl
+ * @since 1.28
+ */
+public interface ProcessBuilderImplementation {
+
+ /**
+ * Creates a process using the specified parameters and environment
+ * configuration.
+ *
+ * @param executable the name of the executable to run
+ * @param workingDirectory the working directory of the created process or
+ * null
as implementation specific default
+ * @param arguments the arguments passed to the process
+ * @param paths the additional paths to add to PATH
environment
+ * variable
+ * @param environment environment variables to configure for the process
+ * @param redirectErrorStream when true
the error stream of
+ * the process should be redirected to standard output stream
+ * @return a process created with specified parameters and environment
+ * configuration
+ * @throws IOException IOException if the process could not be created
+ */
+ @NonNull
+ Process createProcess(@NonNull String executable, @NullAllowed String workingDirectory, @NonNull List arguments,
+ @NonNull List paths, @NonNull Map environment, boolean redirectErrorStream) throws IOException;
+
+}
diff -r f60f09aecc4f extexecution/src/org/netbeans/spi/extexecution/package-info.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extexecution/src/org/netbeans/spi/extexecution/package-info.java Mon Nov 14 19:03:18 2011 +0100
@@ -0,0 +1,51 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+
+/**
+ * The support SPI for creation of external processes.
+ *
+ * @see org.netbeans.spi.extexecution.ProcessBuilderImplementation
+ */
+package org.netbeans.spi.extexecution;
+
diff -r f60f09aecc4f extexecution/test/unit/src/org/netbeans/api/extexecution/ProcessBuilderTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extexecution/test/unit/src/org/netbeans/api/extexecution/ProcessBuilderTest.java Mon Nov 14 19:03:18 2011 +0100
@@ -0,0 +1,166 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.api.extexecution;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.spi.extexecution.ProcessBuilderFactory;
+import org.netbeans.spi.extexecution.ProcessBuilderImplementation;
+
+/**
+ *
+ * @author Petr Hejl
+ */
+public class ProcessBuilderTest extends NbTestCase {
+
+ public ProcessBuilderTest(String name) {
+ super(name);
+ }
+
+ public void testExecutable() throws IOException {
+ TestProcessBuilder testBuilder = new TestProcessBuilder();
+ ProcessBuilder builder = ProcessBuilderFactory.createProcessBuilder(testBuilder, "Test builder");
+
+ try {
+ builder.call();
+ fail("Empty executable does not throw exception");
+ } catch (IllegalStateException ex) {
+ // expected
+ }
+
+ builder.setExecutable("ls");
+ builder.call();
+ assertEquals("ls", testBuilder.getExecutable());
+
+ builder.setExecutable("cd");
+ assertEquals("ls", testBuilder.getExecutable());
+
+ builder.call();
+ assertEquals("cd", testBuilder.getExecutable());
+ }
+
+ public void testWorkingDirectory() throws IOException {
+ TestProcessBuilder testBuilder = new TestProcessBuilder();
+ ProcessBuilder builder = ProcessBuilderFactory.createProcessBuilder(testBuilder, "Test builder");
+ builder.setExecutable("ls");
+
+ builder.call();
+ assertNull(testBuilder.getWorkingDirectory());
+
+ builder.setWorkingDirectory("test");
+ assertNull(testBuilder.getWorkingDirectory());
+
+ builder.call();
+ assertEquals("test", testBuilder.getWorkingDirectory());
+ }
+
+ public void testRedirectErrorStream() throws IOException {
+ TestProcessBuilder testBuilder = new TestProcessBuilder();
+ ProcessBuilder builder = ProcessBuilderFactory.createProcessBuilder(testBuilder, "Test builder");
+ builder.setExecutable("ls");
+
+ builder.call();
+ assertFalse(testBuilder.isRedirectErrorStream());
+
+ builder.setRedirectErrorStream(true);
+ assertFalse(testBuilder.isRedirectErrorStream());
+
+ builder.call();
+ assertTrue(testBuilder.isRedirectErrorStream());
+ }
+
+ private class TestProcessBuilder implements ProcessBuilderImplementation {
+
+ private String executable;
+
+ private String workingDirectory;
+
+ private List arguments;
+
+ private List paths;
+
+ private Map environment;
+
+ private boolean redirectErrorStream;
+
+ @Override
+ public Process createProcess(String executable, String workingDirectory,
+ List arguments, List paths, Map environment, boolean redirectErrorStream) throws IOException {
+
+ this.executable = executable;
+ this.workingDirectory = workingDirectory;
+ this.arguments = arguments;
+ this.paths = paths;
+ this.environment = environment;
+ this.redirectErrorStream = redirectErrorStream;
+
+ return null;
+ }
+
+ public String getExecutable() {
+ return executable;
+ }
+
+ public List getArguments() {
+ return arguments;
+ }
+
+ public List getPaths() {
+ return paths;
+ }
+
+ public Map getEnvironment() {
+ return environment;
+ }
+
+ public boolean isRedirectErrorStream() {
+ return redirectErrorStream;
+ }
+
+ public String getWorkingDirectory() {
+ return workingDirectory;
+ }
+
+ }
+}