Author: ngn Date: Wed May 24 13:29:38 2006 New Revision: 409244 URL: http://svn.apache.org/viewvc?rev=409244&view=rev Log: Adding suggestion for basic Executor interface with a default implementation (not complete, async exec missing) and basic unit test.
Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java (with props) jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteResultHandler.java (with props) jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Executor.java (with props) jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java (with props) jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/MockExecuteResultHandler.java (with props) Modified: jakarta/commons/sandbox/exec/trunk/ (props changed) Propchange: jakarta/commons/sandbox/exec/trunk/ ------------------------------------------------------------------------------ --- svn:ignore (original) +++ svn:ignore Wed May 24 13:29:38 2006 @@ -1,6 +1,9 @@ + target build.properties *.iml *.ipr *.iws - +bin +.classpath +.project Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java?rev=409244&view=auto ============================================================================== --- jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java (added) +++ jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java Wed May 24 13:29:38 2006 @@ -0,0 +1,245 @@ +/* + * Copyright 2006 The Apache Software Foundation + * + * Licensed 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.commons.exec; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +import org.apache.commons.exec.launcher.CommandLauncher; +import org.apache.commons.exec.launcher.CommandLauncherFactory; + +/** + * + */ +public class DefaultExecutor implements Executor { + + private ExecuteStreamHandler streamHandler = new LogStreamHandler(1, 1); + + private File workingDirectory; + + private ExecuteWatchdog watchdog; + + // TODO replace with generic launcher + private CommandLauncher launcher = CommandLauncherFactory + .createVMLauncher(); + + /* + * (non-Javadoc) + * + * @see org.apache.commons.exec.Executor#getStreamHandler() + */ + public ExecuteStreamHandler getStreamHandler() { + return streamHandler; + } + + /* + * (non-Javadoc) + * + * @see org.apache.commons.exec.Executor#setStreamHandler(org.apache.commons.exec.ExecuteStreamHandler) + */ + public void setStreamHandler(ExecuteStreamHandler streamHandler) { + this.streamHandler = streamHandler; + } + + /* + * (non-Javadoc) + * + * @see org.apache.commons.exec.Executor#getWatchdog() + */ + public ExecuteWatchdog getWatchdog() { + return watchdog; + } + + /* + * (non-Javadoc) + * + * @see org.apache.commons.exec.Executor#setWatchdog(org.apache.commons.exec.ExecuteWatchdog) + */ + public void setWatchdog(ExecuteWatchdog watchDog) { + this.watchdog = watchdog; + } + + /* + * (non-Javadoc) + * + * @see org.apache.commons.exec.Executor#getWorkingDirectory() + */ + public File getWorkingDirectory() { + return workingDirectory; + } + + /* + * (non-Javadoc) + * + * @see org.apache.commons.exec.Executor#setWorkingDirectory(java.io.File) + */ + public void setWorkingDirectory(File dir) { + this.workingDirectory = dir; + } + + /* + * (non-Javadoc) + * + * @see org.apache.commons.exec.Executor#execute(java.lang.String[]) + */ + public int execute(final CommandLine command) throws ExecuteException, + IOException { + return execute(command, (Map) null); + } + + /* + * (non-Javadoc) + * + * @see org.apache.commons.exec.Executor#execute(java.lang.String[], + * java.util.Map) + */ + public int execute(final CommandLine command, Map environment) + throws ExecuteException, IOException { + + if (workingDirectory != null && !workingDirectory.exists()) { + throw new IOException(workingDirectory + " doesn't exist."); + } + + final Process process = launch(command, environment, workingDirectory); + + try { + streamHandler.setProcessInputStream(process.getOutputStream()); + streamHandler.setProcessOutputStream(process.getInputStream()); + streamHandler.setProcessErrorStream(process.getErrorStream()); + } catch (IOException e) { + process.destroy(); + throw e; + } + streamHandler.start(); + + try { + // add the process to the list of those to destroy if the VM exits + // + // processDestroyer.add(process); + + if (watchdog != null) { + watchdog.start(process); + } + int exitValue = Executor.INVALID_EXITVALUE; + try { + exitValue = process.waitFor(); + } catch (InterruptedException e) { + process.destroy(); + } + + if (watchdog != null) { + watchdog.stop(); + } + streamHandler.stop(); + closeStreams(process); + + if (watchdog != null) { + try { + watchdog.checkException(); + } catch (Exception e) { + // TODO: include cause + throw new IOException(e.getMessage()); + } + + } + + // TODO check exitValue and throw if not OK + return exitValue; + } finally { + // remove the process to the list of those to destroy if the VM + // exits + // + // processDestroyer.remove(process); + } + } + + /** + * Creates a process that runs a command. + * + * @param command + * the command to run + * @param env + * the environment for the command + * @param dir + * the working directory for the command + * @return the process started + * @throws IOException + * forwarded from the particular launcher used + */ + private Process launch(final CommandLine command, final Map env, + final File dir) throws IOException { + CommandLauncher launcher = this.launcher; + + if (launcher == null) { + throw new IllegalStateException("CommandLauncher can not be null"); + + } + + if (dir != null && !dir.exists()) { + throw new IOException(dir + " doesn't exist."); + } + return launcher.exec(command, env, dir); + } + + /* + * (non-Javadoc) + * + * @see org.apache.commons.exec.Executor#execute(java.lang.String[], + * org.apache.commons.exec.ExecuteResultHandler) + */ + public void execute(final CommandLine command, ExecuteResultHandler handler) + throws ExecuteException, IOException { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see org.apache.commons.exec.Executor#execute(java.lang.String[], + * java.util.Map, org.apache.commons.exec.ExecuteResultHandler) + */ + public void execute(final CommandLine command, final Map environment, + final ExecuteResultHandler handler) throws ExecuteException, IOException { + // TODO Auto-generated method stub + + } + + /** + * Close the streams belonging to the given Process. + * + * @param process + * the <CODE>Process</CODE>. + */ + private void closeStreams(final Process process) { + try { + process.getInputStream().close(); + } catch (IOException eyeOhEx) { + // ignore error + } + try { + process.getOutputStream().close(); + } catch (IOException eyeOhEx) { + // ignore error + } + try { + process.getErrorStream().close(); + } catch (IOException eyeOhEx) { + // ignore error + } + } +} Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java ------------------------------------------------------------------------------ svn:eol-style = native Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteResultHandler.java URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteResultHandler.java?rev=409244&view=auto ============================================================================== --- jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteResultHandler.java (added) +++ jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteResultHandler.java Wed May 24 13:29:38 2006 @@ -0,0 +1,24 @@ +/* + * Copyright 2006 The Apache Software Foundation + * + * Licensed 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.commons.exec; + +public interface ExecuteResultHandler { + + void onProcessComplete(int exitValue); + void onProcessFailed(ExecuteException e); +} Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteResultHandler.java ------------------------------------------------------------------------------ svn:eol-style = native Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Executor.java URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Executor.java?rev=409244&view=auto ============================================================================== --- jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Executor.java (added) +++ jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Executor.java Wed May 24 13:29:38 2006 @@ -0,0 +1,60 @@ +/* + * Copyright 2006 The Apache Software Foundation + * + * Licensed 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.commons.exec; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +public interface Executor { + + /** Invalid exit code. * */ + public static final int INVALID_EXITVALUE = Integer.MAX_VALUE; + + + /* + * StreamHandlers are used for providing input, + * retriving the output. Also used for logging. + */ + ExecuteStreamHandler getStreamHandler(); + void setStreamHandler(ExecuteStreamHandler streamHandler); + + /* + * Watchdog is used to kill of processes running, + * typically, too long time. + */ + ExecuteWatchdog getWatchdog(); + void setWatchdog(ExecuteWatchdog watchDog); + + File getWorkingDirectory(); + void setWorkingDirectory(File dir); + + /* + * Methods for starting synchronous execution. + * Returns process exit value + */ + int execute(CommandLine command) throws ExecuteException, IOException; + int execute(CommandLine command, Map environment) throws ExecuteException, IOException; + + /* + * Methods for starting asynchronous execution. Result provided to callback handler + */ + void execute(CommandLine command, ExecuteResultHandler handler) throws ExecuteException, IOException; + void execute(CommandLine command, Map environment, ExecuteResultHandler handler) throws ExecuteException, IOException; + +} Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Executor.java ------------------------------------------------------------------------------ svn:eol-style = native Added: jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java?rev=409244&view=auto ============================================================================== --- jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java (added) +++ jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java Wed May 24 13:29:38 2006 @@ -0,0 +1,97 @@ +/* + * Copyright 2005 The Apache Software Foundation + * + * Licensed 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.commons.exec; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +public class DefaultExecutorTest extends TestCase { + + private String testDir = "src/test/scripts"; + private ByteArrayOutputStream baos; + private String testScript = TestUtil.resolveScriptForOS(testDir + "/test"); + + protected void setUp() throws Exception { + baos = new ByteArrayOutputStream(); + } + + public void testExecute() throws Exception { + Executor exec = new DefaultExecutor(); + exec.setStreamHandler(new PumpStreamHandler(baos, baos)); + + CommandLine cl = new CommandLine(new File(testScript).getAbsolutePath()); + + int exitValue = exec.execute(cl); + assertEquals("FOO..", baos.toString().trim()); + assertEquals(0, exitValue); + } + + public void testExecuteWithArg() throws Exception { + Executor exec = new DefaultExecutor(); + exec.setStreamHandler(new PumpStreamHandler(baos, baos)); + + CommandLine cl = new CommandLine(testScript); + cl.addArgument("BAR"); + int exitValue = exec.execute(cl); + + assertEquals("FOO..BAR", baos.toString().trim()); + assertEquals(0, exitValue); + } + + public void testExecuteWithEnv() throws Exception { + Executor exec = new DefaultExecutor(); + exec.setStreamHandler(new PumpStreamHandler(baos, baos)); + + Map env = new HashMap(); + env.put("TEST_ENV_VAR", "XYZ"); + + CommandLine cl = new CommandLine(testScript); + + int exitValue = exec.execute(cl, env); + + assertEquals("FOO.XYZ.", baos.toString().trim()); + assertEquals(0, exitValue); + } + + public void disabledtestExecuteAsync() throws Exception { + Executor exec = new DefaultExecutor(); + exec.setStreamHandler(new PumpStreamHandler(baos, baos)); + + CommandLine cl = new CommandLine(testScript); + + MockExecuteResultHandler handler = new MockExecuteResultHandler(); + + exec.execute(cl, handler); + + // wait for script to run + Thread.sleep(1000); + + assertEquals("FOO..", baos.toString().trim()); + assertEquals(0, handler.getExitValue()); + } + + + + protected void tearDown() throws Exception { + baos.close(); + } +} Propchange: jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java ------------------------------------------------------------------------------ svn:eol-style = native Added: jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/MockExecuteResultHandler.java URL: http://svn.apache.org/viewvc/jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/MockExecuteResultHandler.java?rev=409244&view=auto ============================================================================== --- jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/MockExecuteResultHandler.java (added) +++ jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/MockExecuteResultHandler.java Wed May 24 13:29:38 2006 @@ -0,0 +1,53 @@ +/* + * Copyright 2006 The Apache Software Foundation + * + * Licensed 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.commons.exec; + +public class MockExecuteResultHandler implements ExecuteResultHandler { + + private int exitValue; + private ExecuteException exception; + + /* (non-Javadoc) + * @see org.apache.commons.exec.ExecuteResultHandler#onProcessComplete(int) + */ + public void onProcessComplete(int exitValue) { + this.exitValue = exitValue; + } + + /* (non-Javadoc) + * @see org.apache.commons.exec.ExecuteResultHandler#onProcessFailed(org.apache.commons.exec.ExecuteException) + */ + public void onProcessFailed(ExecuteException e) { + this.exception = e; + } + + /** + * @return Returns the exception. + */ + public ExecuteException getException() { + return exception; + } + + /** + * @return Returns the exitValue. + */ + public int getExitValue() { + return exitValue; + } + +} Propchange: jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/MockExecuteResultHandler.java ------------------------------------------------------------------------------ svn:eol-style = native --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]