reorganized CommandProcessor, added open and displayText commands

Commands are categorized in to sections, Keyboard, Mouse, Windows, File,
and Main.
The open command will open an application.
The displayText command displays a status text for a period of time.
Added unit test for CommandProcessor.
This commit is contained in:
Edward Jakubowski
2014-03-25 13:00:29 -04:00
parent f6db3768d9
commit 2e1723f66e
14 changed files with 881 additions and 502 deletions

View File

@@ -0,0 +1,137 @@
package org.synthuse.commands;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import org.synthuse.*;
import com.sun.jna.platform.win32.WinDef.HWND;
public class BaseCommand {
static String WIN_XML = "";
static long LAST_UPDATED_XML = 0;
protected Api api = new Api();
protected CommandProcessor parentProcessor = null;
protected int getExecuteErrorCount() {
return parentProcessor.executeErrorCount;
}
protected void setExecuteErrorCount(int val) {
parentProcessor.executeErrorCount = val;
}
protected String getCurrentCommand() {
return parentProcessor.currentCommandText;
}
protected void setCurrentCommand(String val) {
parentProcessor.currentCommandText = val;
}
protected boolean isProcessorStopped() {
return CommandProcessor.STOP_PROCESSOR.get();
}
public BaseCommand(CommandProcessor cp) { // should pass in the parent command processor
parentProcessor = cp;
}
public void appendError(Exception e) {
setExecuteErrorCount(getExecuteErrorCount() + 1);
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
parentProcessor.lastError += new Timestamp((new Date()).getTime()) + " - " + sw.toString() + "\n";
try {
sw.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void appendError(String msg) {
setExecuteErrorCount(getExecuteErrorCount() + 1);
parentProcessor.lastError += new Timestamp((new Date()).getTime()) + " - " + msg + "\n";
}
public boolean checkArgumentLength(String[] args, int expectedLength) {
if (args.length < expectedLength) {
appendError("Error: expected at least " + expectedLength + " arguments (" + getCurrentCommand() + "[" + args.length + "])");
return false;
}
return true;
}
public boolean checkFirstArgumentLength(String[] args) {
if (args[0].length() <= 0) {
appendError("Error: command '" + getCurrentCommand() + "' failed, expected first argument length > 0");
return false;
}
return true;
}
public boolean checkIsNumeric(String val) {
try {
Long.parseLong(val);
} catch(NumberFormatException e) {
appendError("Error: command '" + getCurrentCommand() + "' failed, was expecting a numeric value instead '" + val + "'");
return false;
}
return true;
}
public boolean whenFalseAppendError(boolean cmdResult) {
if (!cmdResult)
appendError("Error: command '" + getCurrentCommand() + "' failed");
return cmdResult;
}
public HWND findHandleWithXpath(String xpath) {
return findHandleWithXpath(xpath, false);
}
public HWND findHandleWithXpath(String xpath, boolean ignoreFailedFind) {
HWND result = null;
double secondsFromLastUpdate = ((double)(System.nanoTime() - LAST_UPDATED_XML) / 1000000000);
if (secondsFromLastUpdate > CommandProcessor.XML_UPDATE_THRESHOLD) { //default 5 second threshold
WIN_XML = WindowsEnumeratedXml.getXml();
LAST_UPDATED_XML = System.nanoTime();
}
WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath);
String resultStr = "";
List<String> resultList = WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath);
for(String item: resultList) {
if (item.contains("hwnd=")) {
List<String> hwndList = WindowsEnumeratedXml.evaluateXpathGetValues(item, "//@hwnd");
resultStr = hwndList.get(0);
}
else
resultStr = item;
break;
}
result = Api.GetHandleFromString(resultStr);
if (result == null && !ignoreFailedFind)
appendError("Error: Failed to find window handle matching: " + xpath);
return result;
}
public String convertListToString(List<String> listStr, String delimiter) {
StringBuilder result = new StringBuilder("");
for (String item: listStr) {
result.append(item + delimiter);
}
return result.toString();
}
public void killStatusWindow() {
parentProcessor.currentStatusWin.dispose();
parentProcessor.currentStatusWin = null;
}
}

View File

@@ -0,0 +1,59 @@
package org.synthuse.commands;
import java.io.*;
import org.synthuse.*;
public class FileCommands extends BaseCommand {
public FileCommands(CommandProcessor cp) {
super(cp);
}
public String cmdGrepFile(String[] args) throws Exception {
if (!checkArgumentLength(args, 2))
return null;
String filename = args[0];
String pattern = args[1];
StringBuilder result = new StringBuilder("");
FileInputStream fis = null;
BufferedReader br = null;
try {
fis = new FileInputStream(filename);
DataInputStream dis = new DataInputStream(fis);
br = new BufferedReader(new InputStreamReader(dis));
String strLine = "";
while ((strLine = br.readLine()) != null) {
if (strLine.matches(pattern))
result.append(strLine + "\n");
}
}
catch (Exception ex) {
throw ex;
}
finally {
if (fis != null)
fis.close();
if (br != null)
br.close();
}
return result.toString();
}
public String cmdFileSearch(String[] args) {
if (!checkArgumentLength(args, 2))
return null;
String path = args[0];
String filenamePattern = args[1];
StringBuilder result = new StringBuilder("");
File parent = new File(path);
for(File child : parent.listFiles()) {
if (child.isFile() && child.getName().matches(filenamePattern))
result.append(child.getAbsolutePath() + "\n");
else if (child.isDirectory()) {
result.append(cmdFileSearch(new String[] {child.getAbsolutePath(), filenamePattern}));
}
}
return result.toString();
}
}

View File

@@ -0,0 +1,60 @@
package org.synthuse.commands;
import org.synthuse.*;
public class KeyboardCommands extends BaseCommand {
public KeyboardCommands(CommandProcessor commandProcessor) {
super(commandProcessor);
}
public boolean cmdSendKeys(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
return whenFalseAppendError(RobotMacro.sendKeys(args[0]));
}
public boolean cmdKeyDown(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
if (!checkFirstArgumentLength(args))
return false;
char keyChar = args[0].charAt(0);
return RobotMacro.keyDown(keyChar);
}
public boolean cmdKeyUp(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
if (!checkFirstArgumentLength(args))
return false;
char keyChar = args[0].charAt(0);
return RobotMacro.keyUp(keyChar);
}
public boolean cmdKeyCopy(String[] args) {
RobotMacro.copyKey();
return true;
}
public boolean cmdKeyPaste(String[] args) {
RobotMacro.pasteKey();
return true;
}
public boolean cmdKeyEscape(String[] args) {
RobotMacro.escapeKey();
return true;
}
public boolean cmdKeyFunc(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
if (!checkFirstArgumentLength(args))
return false;
int fNum = Integer.parseInt(args[0]);
RobotMacro.functionKey(fNum);
return true;
}
}

View File

@@ -0,0 +1,135 @@
package org.synthuse.commands;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.IOException;
import org.synthuse.*;
import com.sun.jna.platform.win32.WinDef.HWND;
public class MainCommands extends BaseCommand {
public MainCommands(CommandProcessor cp) {
super(cp);
}
public boolean cmdOpen(String[] args) throws IOException {
if (!checkArgumentLength(args, 1))
return false;
Runtime runtime = Runtime.getRuntime();
runtime.exec(args[0]);
return true;
}
public boolean cmdDisplayText(String[] args) throws IOException {
if (!checkArgumentLength(args, 2))
return false;
if (!checkIsNumeric(args[1]))
return false;
this.killStatusWindow();
StatusWindow sw = new StatusWindow(args[0], Integer.parseInt(args[1]));
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
sw.setLocation(dim.width/2-sw.getSize().width/2, dim.height + StatusWindow.Y_BOTTOM_OFFSET - 80 );
return true;
}
public boolean cmdSetSpeed(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
long speed = Long.parseLong(args[0]);
CommandProcessor.SPEED = speed;
return true;
}
public boolean cmdSetTimeout(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
long timeout = Long.parseLong(args[0]);
CommandProcessor.WAIT_TIMEOUT_THRESHOLD = timeout;
return true;
}
public boolean cmdWaitForTitle(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
long totalAttempts = (long) (CommandProcessor.WAIT_TIMEOUT_THRESHOLD / (CommandProcessor.XML_UPDATE_THRESHOLD * 1000));
long attemptCount = 0;
String xpath = "/EnumeratedWindows/win[@TEXT='" + WindowsEnumeratedXml.escapeXmlAttributeValue(args[0].toUpperCase()) + "']";
HWND handle = findHandleWithXpath(xpath, true);
if (handle != null)// first test without a timeout
return true;
while (attemptCount < totalAttempts) {
handle = findHandleWithXpath(xpath, true);
if (handle != null)
break;
try {Thread.sleep((long)(CommandProcessor.XML_UPDATE_THRESHOLD * 1000));} catch (Exception e) {e.printStackTrace();}
++attemptCount;
if (isProcessorStopped())
break;
}
return handle != null;
}
public boolean cmdWaitForText(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
long totalAttempts = (long) (CommandProcessor.WAIT_TIMEOUT_THRESHOLD / (CommandProcessor.XML_UPDATE_THRESHOLD * 1000));
long attemptCount = 0;
String xpath = "//[@TEXT='" + WindowsEnumeratedXml.escapeXmlAttributeValue(args[0].toUpperCase()) + "']";
HWND handle = findHandleWithXpath(xpath, true);
if (handle != null)// first test without a timeout
return true;
while (attemptCount < totalAttempts) {
handle = findHandleWithXpath(xpath, true);
if (handle != null)
break;
try {Thread.sleep((long)(CommandProcessor.XML_UPDATE_THRESHOLD * 1000));} catch (Exception e) {e.printStackTrace();}
++attemptCount;
if (isProcessorStopped())
break;
}
return handle != null;
}
public boolean cmdWaitForClass(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
long totalAttempts = (long) (CommandProcessor.WAIT_TIMEOUT_THRESHOLD / (CommandProcessor.XML_UPDATE_THRESHOLD * 1000));
long attemptCount = 0;
String xpath = "//win[@CLASS='" + WindowsEnumeratedXml.escapeXmlAttributeValue(args[0].toUpperCase()) + "']";
HWND handle = findHandleWithXpath(xpath, true);
if (handle != null)// first test without a timeout
return true;
while (attemptCount < totalAttempts) {
handle = findHandleWithXpath(xpath, true);
if (handle != null)
break;
try {Thread.sleep((long)(CommandProcessor.XML_UPDATE_THRESHOLD * 1000));} catch (Exception e) {e.printStackTrace();}
++attemptCount;
if (isProcessorStopped())
break;
}
return handle != null;
}
public boolean cmdWaitForVisible(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
long totalAttempts = (long) (CommandProcessor.WAIT_TIMEOUT_THRESHOLD / (CommandProcessor.XML_UPDATE_THRESHOLD * 1000));
long attemptCount = 0;
HWND handle = findHandleWithXpath(args[0], true);
if (handle != null)// first test without a timeout
return true;
while (attemptCount < totalAttempts) {
handle = findHandleWithXpath(args[0], true);
if (handle != null)
break;
try {Thread.sleep((long)(CommandProcessor.XML_UPDATE_THRESHOLD * 1000));} catch (Exception e) {e.printStackTrace();}
++attemptCount;
if (isProcessorStopped())
break;
}
return handle != null;
}
}

View File

@@ -0,0 +1,130 @@
package org.synthuse.commands;
import java.awt.Point;
import org.synthuse.*;
import com.sun.jna.platform.win32.WinDef.HWND;
public class MouseCommands extends BaseCommand {
public MouseCommands(CommandProcessor commandProcessor) {
super(commandProcessor);
}
public boolean cmdClick(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
Point p = api.getWindowPosition(handle);
RobotMacro.mouseMove(p.x + parentProcessor.targetOffset.x, p.y + parentProcessor.targetOffset.y);
RobotMacro.leftClickMouse();
return true;
}
public boolean cmdDoubleClick(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
Point p = api.getWindowPosition(handle);
RobotMacro.mouseMove(p.x + parentProcessor.targetOffset.x, p.y + parentProcessor.targetOffset.y);
RobotMacro.doubleClickMouse();
return true;
}
public boolean cmdRightClick(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
Point p = api.getWindowPosition(handle);
RobotMacro.mouseMove(p.x + parentProcessor.targetOffset.x, p.y + parentProcessor.targetOffset.y);
RobotMacro.rightClickMouse();
return true;
}
public boolean cmdMouseDown(String[] args) {
RobotMacro.leftMouseDown();
return true;
}
public boolean cmdMouseUp(String[] args) {
RobotMacro.leftMouseUp();
return true;
}
public boolean cmdMouseDownRight(String[] args) {
RobotMacro.rightMouseDown();
return true;
}
public boolean cmdMouseUpRight(String[] args) {
RobotMacro.rightMouseUp();
return true;
}
public boolean cmdMouseMove(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
Point p = api.getWindowPosition(handle);
RobotMacro.mouseMove(p.x + parentProcessor.targetOffset.x, p.y + parentProcessor.targetOffset.y);
//System.out.println("point " + p.x + "," + p.y);
return true;
}
public boolean cmdSetTargetOffset(String[] args) {
if (!checkArgumentLength(args, 2))
return false;
int x = Integer.parseInt(args[0]);
int y = Integer.parseInt(args[1]);
parentProcessor.targetOffset.x = x;
parentProcessor.targetOffset.y = y;
return true;
}
public boolean cmdMouseMoveXy(String[] args) {
if (!checkArgumentLength(args, 2))
return false;
int x = Integer.parseInt(args[0]);
int y = Integer.parseInt(args[1]);
RobotMacro.mouseMove(x, y);
return true;
}
public boolean cmdWinClick(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
api.sendClick(handle);
return true;
}
public boolean cmdWinDoubleClick(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
api.sendDoubleClick(handle);
return true;
}
public boolean cmdWinRightClick(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
api.sendRightClick(handle);
return true;
}
}

View File

@@ -0,0 +1,113 @@
package org.synthuse.commands;
import org.synthuse.*;
import com.sun.jna.platform.win32.WinDef.HWND;
public class WindowsCommands extends BaseCommand {
public WindowsCommands(CommandProcessor cp) {
super(cp);
}
public boolean cmdWindowFocus(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
api.activateWindow(handle);
//api.showWindow(handle);
return true;
}
public boolean cmdWindowMinimize(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
api.minimizeWindow(handle);
return true;
}
public boolean cmdWindowMaximize(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
api.maximizeWindow(handle);
return true;
}
public boolean cmdWindowRestore(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
api.restoreWindow(handle);
return true;
}
public boolean cmdWindowHide(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
api.hideWindow(handle);
return true;
}
public boolean cmdWindowShow(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
api.showWindow(handle);
return true;
}
public boolean cmdWindowSwitchToThis(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
api.switchToThisWindow(handle, true);
return true;
}
public boolean cmdWindowClose(String[] args) {
if (!checkArgumentLength(args, 1))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
api.closeWindow(handle);
return true;
}
public boolean cmdSetText(String[] args) {
if (!checkArgumentLength(args, 2))
return false;
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return false;
api.sendWmSetText(handle, args[1]);
return true;
}
public String cmdGetText(String[] args) {
if (!checkArgumentLength(args, 1))
return "";
HWND handle = findHandleWithXpath(args[0]);
if (handle == null)
return "";
return api.sendWmGetText(handle);
}
}