diff -r d2548a0f0308 extexecution/apichanges.xml --- a/extexecution/apichanges.xml Mon Feb 08 18:27:00 2010 +0100 +++ b/extexecution/apichanges.xml Wed Feb 10 14:41:40 2010 +0100 @@ -110,6 +110,20 @@ + + New API method to avoid reset of custom IO + + + + + + Added configuration method to ExecutionDescriptor to make + reset of IO optional for custom IO. + + + + + New SPI for improved external process termination @@ -124,7 +138,6 @@ - Configurable charset for process streams diff -r d2548a0f0308 extexecution/manifest.mf --- a/extexecution/manifest.mf Mon Feb 08 18:27:00 2010 +0100 +++ b/extexecution/manifest.mf Wed Feb 10 14:41:40 2010 +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.19 +OpenIDE-Module-Specification-Version: 1.20 diff -r d2548a0f0308 extexecution/src/org/netbeans/api/extexecution/ExecutionDescriptor.java --- a/extexecution/src/org/netbeans/api/extexecution/ExecutionDescriptor.java Mon Feb 08 18:27:00 2010 +0100 +++ b/extexecution/src/org/netbeans/api/extexecution/ExecutionDescriptor.java Wed Feb 10 14:41:40 2010 +0100 @@ -78,6 +78,8 @@ private final boolean controllable; + private final boolean noReset; + private boolean outLineBased; private boolean errLineBased; @@ -124,6 +126,7 @@ this.rerunCondition = data.rerunCondition; this.optionsPath = data.optionsPath; this.charset = data.charset; + this.noReset = data.noReset; } /** @@ -276,6 +279,33 @@ } /** + * Returns a descriptor with configured no reset flag. When configured + * value is true the output window won't be cleared before + * the execution. Valid only for custom {@link InputOutput} configured via + * {@link #inputOutput(org.openide.windows.InputOutput)}, ignored in all + * other cases. + *

+ * The default (not configured) value is false. + *

+ * All other properties of the returned descriptor are inherited from + * this. + * + * @param noReset no reset flag + * @return new descriptor with configured no reset flag + * @since 1.20 + */ + @NonNull + @CheckReturnValue + public ExecutionDescriptor noReset(boolean noReset) { + DescriptorData data = new DescriptorData(this); + return new ExecutionDescriptor(data.noReset(noReset)); + } + + boolean noReset() { + return noReset; + } + + /** * Returns a descriptor with configured flag indicating line based standard * output. When configured value is true the default printing * processor will always wait for the whole line before converting and @@ -657,6 +687,8 @@ private boolean controllable; + private boolean noReset; + private boolean outLineBased; private boolean errLineBased; @@ -699,6 +731,7 @@ this.rerunCondition = descriptor.rerunCondition; this.optionsPath = descriptor.optionsPath; this.charset = descriptor.charset; + this.noReset = descriptor.noReset; } public DescriptorData inputOutput(InputOutput io) { @@ -731,6 +764,11 @@ return this; } + public DescriptorData noReset(boolean noReset) { + this.noReset = noReset; + return this; + } + public DescriptorData outLineBased(boolean outLineBased) { this.outLineBased = outLineBased; return this; diff -r d2548a0f0308 extexecution/src/org/netbeans/api/extexecution/ExecutionService.java --- a/extexecution/src/org/netbeans/api/extexecution/ExecutionService.java Mon Feb 08 18:27:00 2010 +0100 +++ b/extexecution/src/org/netbeans/api/extexecution/ExecutionService.java Wed Feb 10 14:41:40 2010 +0100 @@ -457,14 +457,20 @@ * @param inputOutput output window to configure */ private void configureInputOutput(InputOutput inputOutput) { - try { - inputOutput.getOut().reset(); - } catch (IOException exc) { - LOGGER.log(Level.INFO, null, exc); + if (inputOutput == InputOutput.NULL) { + return; } - // Note - do this AFTER the reset() call above; if not, weird bugs occur - inputOutput.setErrSeparated(false); + if (descriptor.getInputOutput() == null || !descriptor.noReset()) { + try { + inputOutput.getOut().reset(); + } catch (IOException exc) { + LOGGER.log(Level.INFO, null, exc); + } + + // Note - do this AFTER the reset() call above; if not, weird bugs occur + inputOutput.setErrSeparated(false); + } // Open I/O window now. This should probably be configurable. if (descriptor.isFrontWindow()) { diff -r d2548a0f0308 extexecution/test/unit/src/org/netbeans/api/extexecution/ExecutionServiceTest.java --- a/extexecution/test/unit/src/org/netbeans/api/extexecution/ExecutionServiceTest.java Mon Feb 08 18:27:00 2010 +0100 +++ b/extexecution/test/unit/src/org/netbeans/api/extexecution/ExecutionServiceTest.java Wed Feb 10 14:41:40 2010 +0100 @@ -43,6 +43,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.Reader; import java.lang.reflect.InvocationTargetException; import java.nio.charset.Charset; import java.util.LinkedList; @@ -55,12 +56,17 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import javax.swing.Action; import org.netbeans.api.extexecution.input.InputProcessor; import org.netbeans.api.extexecution.input.InputProcessors; import org.netbeans.junit.NbTestCase; import org.netbeans.modules.extexecution.InputOutputManager; import org.netbeans.api.extexecution.input.TestInputUtils; import org.netbeans.api.extexecution.input.TestLineProcessor; +import org.openide.windows.IOProvider; +import org.openide.windows.InputOutput; +import org.openide.windows.OutputListener; +import org.openide.windows.OutputWriter; /** * @@ -377,6 +383,43 @@ } } + public void testIOReset() throws InterruptedException, InvocationTargetException, ExecutionException { + TestProcess process = new TestProcess(0); + TestCallable callable = new TestCallable(); + callable.addProcess(process); + + InputOutput io = IOProvider.getDefault().getIO("Test", new Action[] {}); + TestInputOutput testIO = new TestInputOutput(io); + + ExecutionDescriptor descriptor = new ExecutionDescriptor() + .inputOutput(testIO).noReset(true); + ExecutionService service = ExecutionService.newService( + callable, descriptor, "Test"); + + Future task = service.run(); + assertNotNull(task); + process.destroy(); + assertEquals(0, task.get().intValue()); + + assertFalse(testIO.isReset()); + + // now with enabled + process = new TestProcess(0); + callable = new TestCallable(); + callable.addProcess(process); + + testIO = new TestInputOutput(io); + descriptor = new ExecutionDescriptor().inputOutput(testIO); + service = ExecutionService.newService(callable, descriptor, "Test"); + + task = service.run(); + assertNotNull(task); + process.destroy(); + assertEquals(0, task.get().intValue()); + + assertTrue(testIO.isReset()); + } + private static InputOutputManager.InputOutputData getInputOutput(String name, boolean actions, String optionsPath) { @@ -586,4 +629,105 @@ } } + private static class TestInputOutput implements InputOutput { + + private final InputOutput io; + + private volatile boolean reset; + + public TestInputOutput(InputOutput io) { + this.io = io; + } + + public boolean isReset() { + return reset; + } + + public void reset() { + this.reset = true; + } + + public void setOutputVisible(boolean value) { + io.setOutputVisible(value); + } + + public void setInputVisible(boolean value) { + io.setInputVisible(value); + } + + public void setFocusTaken(boolean value) { + io.setFocusTaken(value); + } + + public void setErrVisible(boolean value) { + io.setErrVisible(value); + } + + public void setErrSeparated(boolean value) { + io.setErrSeparated(value); + } + + public void select() { + io.select(); + } + + public boolean isFocusTaken() { + return io.isFocusTaken(); + } + + public boolean isErrSeparated() { + return io.isErrSeparated(); + } + + public boolean isClosed() { + return io.isClosed(); + } + + public OutputWriter getOut() { + return new TestOutputWriter(this, io.getOut()); + } + + public Reader getIn() { + return io.getIn(); + } + + public OutputWriter getErr() { + return io.getErr(); + } + + public Reader flushReader() { + return io.flushReader(); + } + + public void closeInputOutput() { + io.closeInputOutput(); + } + } + + private static class TestOutputWriter extends OutputWriter { + + private final TestInputOutput io; + + private final OutputWriter ow; + + public TestOutputWriter(TestInputOutput io, OutputWriter ow) { + super(ow); + this.io = io; + this.ow = ow; + } + + public void reset() throws IOException { + ow.reset(); + io.reset(); + } + + public void println(String s, OutputListener l, boolean important) throws IOException { + ow.println(s, l, important); + } + + public void println(String s, OutputListener l) throws IOException { + ow.println(s, l); + } + + } } diff -r d2548a0f0308 extexecution/test/unit/src/org/netbeans/api/extexecution/input/InputProcessorsTest.java --- a/extexecution/test/unit/src/org/netbeans/api/extexecution/input/InputProcessorsTest.java Mon Feb 08 18:27:00 2010 +0100 +++ b/extexecution/test/unit/src/org/netbeans/api/extexecution/input/InputProcessorsTest.java Wed Feb 10 14:41:40 2010 +0100 @@ -39,8 +39,6 @@ package org.netbeans.api.extexecution.input; -import org.netbeans.api.extexecution.input.InputProcessor; -import org.netbeans.api.extexecution.input.InputProcessors; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList;