/* MonkeyTalk - a cross-platform functional testing tool Copyright (C) 2012 Gorilla Logic, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.gorillalogic.fonemonkey.automators; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.gorillalogic.fonemonkey.Log; import com.gorillalogic.fonemonkey.exceptions.FoneMonkeyScriptFailure; import com.gorillalogic.monkeytalk.automators.AutomatorConstants; /** */ public class AppAutomator extends AutomatorBase { static { Log.log("Initializing AppAutomator"); } @Override public String getComponentType() { return AutomatorConstants.TYPE_APP; } @Override public String play(String action, final String... args) { if (action.equalsIgnoreCase(AutomatorConstants.ACTION_EXEC) || action.equalsIgnoreCase(AutomatorConstants.ACTION_EXECANDRET)) { // build a list of params List<String> params = new ArrayList<String>(Arrays.asList(args)); if (action.equalsIgnoreCase(AutomatorConstants.ACTION_EXECANDRET)) { // pop off first param (returned variable name) params.remove(0); } // get class name and method name String className = getMonkeyID(); String methodName = params.remove(0); String name = "Method '" + methodName + "' on Class '" + className + "'"; System.out.println("AppAutomator: looking for " + name); Class<?> clazz = null; try { // find the class and method -> looking for a static method with varargs // ex: public static String foo(String... args) clazz = Class.forName(className); Method method = clazz.getDeclaredMethod(methodName, String[].class); System.out.println("AppAutomator: found '" + method.toGenericString() + "'" + ", isPublic=" + Modifier.isPublic(method.getModifiers()) + ", isStatic=" + Modifier.isStatic(method.getModifiers()) + ", isVarArgs=" + method.isVarArgs() + ", returns=" + method.getReturnType().getSimpleName()); // force method to be both public AND static if (!Modifier.isPublic(method.getModifiers()) || !Modifier.isStatic(method.getModifiers())) { throw new IllegalArgumentException(name + " must be public static, but it is " + Modifier.toString(method.getModifiers() & ~Modifier.TRANSIENT)); } if (method.getReturnType() != String.class && method.getReturnType() != void.class) { throw new IllegalArgumentException(name + " must return String or void, but it returns " + method.getReturnType().getSimpleName()); } // invoke it String val = (String) method.invoke(null, (Object) params.toArray(new String[params.size()])); System.out.println("AppAutomator: val=" + val); return val; } catch (ClassNotFoundException ex) { throw new IllegalArgumentException("Class '" + className + "' not found"); } catch (NoSuchMethodException ex) { if (clazz != null) { for (Method m : clazz.getMethods()) { if (m.getName().equals(methodName)) { throw new FoneMonkeyScriptFailure(name + " must take a single varargs String param"); } } } throw new IllegalArgumentException("Method '" + methodName + "' not found on Class '" + className + "'"); } catch (Exception ex) { ex.printStackTrace(); throw new FoneMonkeyScriptFailure(ex.getMessage()); } } return null; } }