calabash-android 0.4.0.pre6 → 0.4.0.pre7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/bin/calabash-android +7 -0
  2. data/bin/calabash-android-build.rb +1 -1
  3. data/bin/calabash-android-console.rb +1 -1
  4. data/bin/calabash-android-run.rb +1 -1
  5. data/calabash-android.gemspec +1 -0
  6. data/irbrc +2 -0
  7. data/lib/calabash-android/helpers.rb +4 -2
  8. data/lib/calabash-android/lib/TestServer.apk +0 -0
  9. data/lib/calabash-android/operations.rb +31 -22
  10. data/lib/calabash-android/version.rb +1 -1
  11. data/test-server/instrumentation-backend/.classpath +0 -1
  12. data/test-server/instrumentation-backend/antlr/UIQuery.g +11 -2
  13. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Command.java +4 -3
  14. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/FranklyResult.java +95 -0
  15. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Result.java +7 -1
  16. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/HttpServer.java +15 -23
  17. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/location/FakeGPSLocation.java +13 -10
  18. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/CalabashChromeClient.java +136 -36
  19. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpBodyHtml.java +38 -18
  20. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpHtml.java +38 -16
  21. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/EnterTextByCssSelector.java +94 -66
  22. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ExecuteAsyncJavascript.java +55 -33
  23. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ExecuteJavascript.java +54 -31
  24. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/JavaScriptOperation.java +44 -0
  25. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/PressByCssSelector.java +52 -27
  26. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/QueryHelper.java +39 -32
  27. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ScrollTo.java +56 -41
  28. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetPropertyByCssSelector.java +50 -25
  29. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetText.java +19 -22
  30. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/CompletedFuture.java +40 -0
  31. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/InvocationOperation.java +201 -0
  32. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Operation.java +7 -0
  33. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/PropertyOperation.java +56 -0
  34. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Query.java +144 -72
  35. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQuery.tokens +15 -12
  36. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQueryResultVoid.java +22 -0
  37. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ViewMapper.java +38 -11
  38. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryLexer.java +226 -109
  39. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryParser.java +237 -84
  40. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/PartialFutureList.java +100 -0
  41. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryAST.java +1 -1
  42. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTClassName.java +26 -22
  43. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTWith.java +170 -102
  44. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryEvaluator.java +54 -155
  45. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryUtils.java +97 -2
  46. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryVisibility.java +32 -0
  47. metadata +27 -5
  48. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Query.java +0 -24
  49. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Touch.java +0 -44
  50. data/test-server/instrumentation-backend/tests/sh/calaba/instrumentationbackend/query/tests/UIQueryTest.java +0 -134
@@ -1,7 +1,6 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
3
 
4
- import java.util.HashMap;
5
4
  import java.util.List;
6
5
  import java.util.Map;
7
6
 
@@ -9,60 +8,76 @@ import sh.calaba.instrumentationbackend.InstrumentationBackend;
9
8
  import sh.calaba.instrumentationbackend.Result;
10
9
  import sh.calaba.instrumentationbackend.actions.Action;
11
10
  import sh.calaba.instrumentationbackend.actions.Actions;
12
- import sh.calaba.org.codehaus.jackson.map.ObjectMapper;
13
- import sh.calaba.org.codehaus.jackson.type.TypeReference;
14
11
  import android.test.TouchUtils;
15
12
  import android.webkit.WebView;
16
13
 
17
14
 
18
15
  public class ScrollTo implements Action {
19
-
20
- @Override
16
+
17
+ @Override
21
18
  public Result execute(String... args) {
22
19
  //TODO: Should do horizontal scrolling if needed
23
- String queryResult = QueryHelper.executeJavascriptInWebview("calabash.js", args[1], args[0]);
24
- CalabashChromeClient calabashChromeClient = CalabashChromeClient.findAndPrepareWebViews().get(0);
25
- final WebView webView = calabashChromeClient.getWebView();
26
- webView.scrollTo(0, 0);
27
- QueryHelper.getScreenCoordinatesForCenter(findFirstRect(queryResult));
28
- int scrolledTo = webView.getScrollY();
29
- while (!isVisible(findFirstRect(queryResult), calabashChromeClient)) {
30
- TouchUtils.dragQuarterScreenUp(Actions.parentTestCase, InstrumentationBackend.solo.getCurrentActivity());
31
- if (scrolledTo != webView.getScrollY()) {
32
- scrolledTo = webView.getScrollY();
33
- } else {
34
- return new Result(false, "Tried scrolling but the center of the element never became visible.");
35
- }
36
- }
37
-
38
- return new Result(true, "");
20
+ final String uiQuery = "webView " + args[0] + ":'"+ args[1] + "'";
21
+
22
+ CalabashChromeClient calabashChromeClient = CalabashChromeClient.findAndPrepareWebViews().get(0);
23
+ WebView webView = calabashChromeClient.getWebView();
24
+
25
+ scrollToTop(webView);
26
+
27
+ while (keepScrolling(uiQuery, webView)) {
28
+ TouchUtils.dragQuarterScreenUp(Actions.parentTestCase, InstrumentationBackend.solo.getCurrentActivity());
29
+ }
30
+
31
+ return new Result(isVisible(uiQuery, webView), "");
39
32
  }
40
33
 
34
+ private void scrollToTop(final WebView webView) {
35
+ InstrumentationBackend.instrumentation.runOnMainSync(new Runnable() {
36
+ @Override
37
+ public void run() {
38
+ webView.scrollTo(0, 0);
39
+ }
40
+ });
41
+ }
41
42
 
43
+ private boolean keepScrolling(String uiQuery, WebView webView) {
44
+ int centerY = getCenterY(uiQuery, webView);
45
+ System.out.println("Keep scrolling centerY: "+ centerY);
42
46
 
43
- private Map<String, Object> findFirstRect(String queryResult) {
44
- try {
45
- List<HashMap<String,Object>> p = new ObjectMapper().readValue(queryResult, new TypeReference<List<HashMap<String,Object>>>(){});
46
-
47
- if (p.isEmpty()) {
48
- throw new RuntimeException("No element found");
49
- }
50
- System.out.println(p);
51
- final Map<String, Object> firstRect = QueryHelper.findFirstVisibleRectangle(p);
52
- return firstRect;
53
- } catch (Exception e) {
54
- throw new RuntimeException(e);
55
- }
47
+ int[] location = new int[2];
48
+ webView.getLocationOnScreen(location);
49
+ int top = location[1];
50
+ int bottom = top + webView.getHeight();
56
51
 
57
- }
52
+ System.out.println("isVisible top: "+ top);
53
+ System.out.println("isVisible bottom: "+ bottom);
54
+
55
+ return centerY > bottom;
56
+ }
57
+
58
+ private boolean isVisible(String uiQuery, WebView webView) {
59
+ int centerY = getCenterY(uiQuery, webView);
60
+ System.out.println("isVisible centerY: "+ centerY);
61
+
62
+ int[] location = new int[2];
63
+ webView.getLocationOnScreen(location);
64
+ int top = location[1];
65
+ int bottom = top + webView.getHeight();
66
+ System.out.println("isVisible top: "+ top);
67
+ System.out.println("isVisible bottom: "+ bottom);
68
+
69
+ return top < centerY && centerY < bottom;
70
+ }
58
71
 
59
- private boolean isVisible(Map<String, Object> rectangle, CalabashChromeClient calabashChromeClient) {
60
- WebView webView = calabashChromeClient.getWebView();
61
- int windowTop = webView.getScrollY();
62
- int windowBottom = webView.getScrollY() + webView.getHeight();
63
- int centerY = (int) ((Integer)rectangle.get("center_y") * webView.getScale());
72
+ @SuppressWarnings({ "rawtypes", "unchecked" })
73
+ private int getCenterY(String uiQuery, WebView webView) {
74
+ List queryResult = new sh.calaba.instrumentationbackend.query.Query(uiQuery).executeQuery();
75
+ if (queryResult.isEmpty()) {
76
+ throw new RuntimeException("Query found no elements");
77
+ }
78
+ final Map<String, Object> firstVisibleRectangle = QueryHelper.findFirstVisibleRectangle(queryResult);
64
79
 
65
- return windowTop < centerY && centerY < windowBottom;
80
+ return Math.round((Float)firstVisibleRectangle.get("center_y"));
66
81
  }
67
82
 
68
83
  @Override
@@ -1,42 +1,67 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
3
 
4
- import sh.calaba.instrumentationbackend.InstrumentationBackend;
4
+ import java.util.ArrayList;
5
+ import java.util.List;
6
+ import java.util.concurrent.Callable;
7
+
5
8
  import sh.calaba.instrumentationbackend.Result;
6
- import sh.calaba.instrumentationbackend.TestHelpers;
7
9
  import sh.calaba.instrumentationbackend.actions.Action;
10
+ import sh.calaba.instrumentationbackend.actions.webview.CalabashChromeClient.WebFuture;
11
+ import sh.calaba.instrumentationbackend.query.ast.UIQueryUtils;
8
12
  import android.webkit.WebView;
9
13
 
10
14
 
11
15
  public class SetPropertyByCssSelector implements Action {
12
16
 
13
- @Override
17
+ @SuppressWarnings({ "unchecked", "rawtypes" })
18
+ @Override
14
19
  public Result execute(String... args) {
15
- String cssSelector = args[0];
16
- String propertyName = args[1];
17
- String value = args[2];
18
-
19
- for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
20
- WebView webView = ccc.getWebView();
20
+ final String cssSelector = args[0];
21
+ final String propertyName = args[1];
22
+ final String value = args[2];
23
+
24
+ List<WebFuture> webResults = (List<WebFuture>) UIQueryUtils.evaluateSyncInMainThread(new Callable() {
21
25
 
22
- final String assignment = "document.querySelector(\"" + cssSelector + "\")." + propertyName + " = " + value + ";";
23
- System.out.println(assignment);
24
- webView.loadUrl("javascript:(function() {" +
25
- assignment +
26
- "prompt('calabash:true');" +
27
- "})()");
28
- String r = ccc.getResult();
29
- System.out.println("setPropertyByCssSelector: " + r);
30
- if ("true".equals(r)) {
31
- TestHelpers.wait(0.3);
32
- return Result.successResult();
33
- }
34
- }
26
+ public Object call() throws Exception {
27
+
28
+ List<WebFuture> webResults = new ArrayList();
29
+ for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
30
+ WebView webView = ccc.getWebView();
31
+
32
+ final String assignment = "document.querySelector(\"" + cssSelector + "\")." + propertyName + " = " + value + ";";
33
+ System.out.println(assignment);
34
+ webView.loadUrl("javascript:(function() {" +
35
+ assignment +
36
+ "prompt('calabash:true');" +
37
+ "})()");
38
+ webResults.add(ccc.getResult());
39
+ }
35
40
 
36
- return new Result(false,"No WebView found");
37
- }
41
+ return webResults;
42
+
43
+ }
44
+ });
45
+
46
+ List<String> allResults = new ArrayList<String>(webResults.size());
47
+ boolean success = false;
48
+ for (WebFuture f : webResults) {
49
+ String result = f.getAsString();
50
+ allResults.add(result);
51
+ if ("true".equals(result)) {
52
+ success = true;
53
+ }
54
+ }
55
+
56
+ if (allResults.size() == 0) {
57
+ return new Result(false, "No WebView found");
58
+ }
59
+ else {
60
+ return new Result(success, allResults);
61
+ }
62
+ }
38
63
 
39
- @Override
64
+ @Override
40
65
  public String key() {
41
66
  return "set_property_by_css_selector";
42
67
  }
@@ -1,14 +1,12 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
3
 
4
- import java.util.HashMap;
5
4
  import java.util.List;
6
5
  import java.util.Map;
7
6
 
8
7
  import sh.calaba.instrumentationbackend.Result;
9
8
  import sh.calaba.instrumentationbackend.actions.Action;
10
- import sh.calaba.org.codehaus.jackson.map.ObjectMapper;
11
- import sh.calaba.org.codehaus.jackson.type.TypeReference;
9
+ import sh.calaba.instrumentationbackend.actions.webview.CalabashChromeClient.WebFuture;
12
10
 
13
11
 
14
12
  public class SetText implements Action {
@@ -18,26 +16,25 @@ public class SetText implements Action {
18
16
  * args[1]: xpath or css selector
19
17
  * args[2]: text to enter into the first selected element
20
18
  */
21
- @Override
22
- public Result execute(String... args) {
23
- try {
24
- String queryResult = QueryHelper.executeJavascriptInWebview("calabash.js", args[1], args[0]);
25
- List<HashMap<String,Object>> p = new ObjectMapper().readValue(queryResult, new TypeReference<List<HashMap<String,Object>>>(){});
26
-
27
- if (p.isEmpty()) {
28
- throw new RuntimeException("No element found");
29
- }
30
- Map<String, Object> firstElement = QueryHelper.findFirstVisibleElement(p);
31
- //TODO: Hack! Should be serialized instead of removed
32
- firstElement.remove("class");
33
- firstElement.remove("html");
34
- String firstElementJson = QueryHelper.toJsonString(firstElement);
35
-
36
- String result = QueryHelper.executeJavascriptInWebview("set_text.js", firstElementJson, args[2]);
37
- return new Result(true, result);
38
- } catch (Exception e) {
39
- throw new RuntimeException(e);
19
+ @SuppressWarnings({ "rawtypes", "unchecked"})
20
+ @Override
21
+ public Result execute(final String... args) {
22
+ final String uiQuery = "webView " + args[0] + ":'"+ args[1] + "'";
23
+ List queryResult = new sh.calaba.instrumentationbackend.query.Query(uiQuery).executeQuery();
24
+ if (queryResult.isEmpty()) {
25
+ throw new RuntimeException("No element found");
40
26
  }
27
+ Map<String, Object> firstElement = QueryHelper.findFirstVisibleElement(queryResult);
28
+ //TODO: Hack! Should be serialized instead of removed
29
+ CalabashChromeClient client = CalabashChromeClient.findAndPrepareWebViews().get(0);
30
+ firstElement.remove("class");
31
+ firstElement.remove("webView");
32
+ firstElement.remove("html");
33
+ String firstElementJson = QueryHelper.toJsonString(firstElement);
34
+
35
+ WebFuture result = QueryHelper.executeAsyncJavascriptInWebviews(client.getWebView(),"set_text.js", firstElementJson, args[2]);
36
+
37
+ return new Result(true,result.getAsString());
41
38
  }
42
39
 
43
40
  @Override
@@ -0,0 +1,40 @@
1
+ package sh.calaba.instrumentationbackend.query;
2
+
3
+ import java.util.concurrent.ExecutionException;
4
+ import java.util.concurrent.Future;
5
+ import java.util.concurrent.TimeUnit;
6
+ import java.util.concurrent.TimeoutException;
7
+
8
+ public class CompletedFuture<T> implements Future<T> {
9
+ private final T result;
10
+
11
+ public CompletedFuture(final T result) {
12
+ this.result = result;
13
+ }
14
+
15
+ @Override
16
+ public boolean cancel(final boolean b) {
17
+ return false;
18
+ }
19
+
20
+ @Override
21
+ public boolean isCancelled() {
22
+ return false;
23
+ }
24
+
25
+ @Override
26
+ public boolean isDone() {
27
+ return true;
28
+ }
29
+
30
+ @Override
31
+ public T get() throws InterruptedException, ExecutionException {
32
+ return this.result;
33
+ }
34
+
35
+ @Override
36
+ public T get(long timeout, TimeUnit unit) throws InterruptedException,
37
+ ExecutionException, TimeoutException {
38
+ return get();
39
+ }
40
+ }
@@ -0,0 +1,201 @@
1
+ package sh.calaba.instrumentationbackend.query;
2
+
3
+ import java.lang.reflect.Method;
4
+ import java.util.List;
5
+ import java.util.concurrent.atomic.AtomicReference;
6
+
7
+ import sh.calaba.instrumentationbackend.InstrumentationBackend;
8
+
9
+ public class InvocationOperation implements Operation {
10
+
11
+ private final String methodName;
12
+ @SuppressWarnings("rawtypes")
13
+ private final List arguments;
14
+ private final Class<?>[] classes;
15
+ private final Class<?>[] classesWithCharseq;
16
+
17
+ @SuppressWarnings("rawtypes")
18
+ public InvocationOperation(String methodName, List arguments) {
19
+ this.methodName = methodName;
20
+ this.arguments = arguments;
21
+ this.classes = extractArgumentTypes(false);
22
+ this.classesWithCharseq = extractArgumentTypes(true);
23
+ }
24
+
25
+ @SuppressWarnings("rawtypes")
26
+ @Override
27
+ public Object apply(final Object o) throws Exception {
28
+ final AtomicReference ref = new AtomicReference();
29
+ final AtomicReference<Exception> refEx = new AtomicReference<Exception>();
30
+
31
+ InstrumentationBackend.instrumentation.runOnMainSync(new Runnable() {
32
+
33
+ @SuppressWarnings("unchecked")
34
+ @Override
35
+ public void run() {
36
+ try {
37
+ Method method = o.getClass().getMethod(InvocationOperation.this.methodName, InvocationOperation.this.classes);
38
+ method.setAccessible(true);
39
+ try {
40
+ Object result;
41
+ if( method.getReturnType().equals(Void.TYPE)){
42
+ invokeMethod(o, method);
43
+ result = "<VOID>";
44
+ }
45
+ else {
46
+ result = invokeMethod(o, method);
47
+ }
48
+ ref.set(result);
49
+ return;
50
+ } catch (Exception e) {
51
+ refEx.set(e);
52
+ return;
53
+ }
54
+ } catch (NoSuchMethodException e) {
55
+ try {
56
+ Method method = o.getClass().getMethod(InvocationOperation.this.methodName, InvocationOperation.this.classesWithCharseq);
57
+ method.setAccessible(true);
58
+ try {
59
+ Object result;
60
+ if( method.getReturnType().equals(Void.TYPE)){
61
+ invokeMethod(o, method);
62
+ result = "<VOID>";
63
+ }
64
+ else {
65
+ result = invokeMethod(o, method);
66
+ }
67
+ ref.set(result);
68
+ return;
69
+ } catch (Exception ee) {
70
+ refEx.set(e);
71
+ return;
72
+ }
73
+ } catch (NoSuchMethodException ee) {
74
+ System.out.println("Method not found with correct argument types. Trying to type convert.");
75
+ }
76
+ }
77
+ //Warning: Slow path
78
+ Method[] methods = o.getClass().getMethods();
79
+ for (Method m : methods) {
80
+ if (m.getName().equals(InvocationOperation.this.methodName)) {
81
+ Class<?>[] parameterTypes = m.getParameterTypes();
82
+ if (parameterTypes.length == InvocationOperation.this.classes.length && areArgumentsConvertibleTo(parameterTypes)) {
83
+ try {
84
+ Object result;
85
+ if( m.getReturnType().equals(Void.TYPE)){
86
+ invokeMethod(o, m);
87
+ result = "<VOID>";
88
+ }
89
+ else {
90
+ result = invokeMethod(o, m);
91
+ }
92
+ ref.set(result);
93
+ return;
94
+ } catch (Exception e) {
95
+ refEx.set(e);
96
+ return;
97
+ }
98
+
99
+ }
100
+ }
101
+ }
102
+
103
+ }
104
+
105
+ });
106
+
107
+ if (refEx.get() != null) {
108
+ throw refEx.get();
109
+ }
110
+ return ref.get();
111
+ }
112
+
113
+ @SuppressWarnings("rawtypes")
114
+ private Class[] extractArgumentTypes(boolean convertStringCharSeq) {
115
+ Class[] types = new Class[arguments.size()];
116
+ for (int i=0;i<arguments.size(); i++) {
117
+ Object o = arguments.get(i);
118
+ if (o != null) {
119
+ Class<?> c = o.getClass();
120
+ if (convertStringCharSeq && c.equals(String.class)) {
121
+ c = CharSequence.class;//Android API specific optimization
122
+ }
123
+ types[i] = c;
124
+ }
125
+ else {
126
+ types[i] = null;
127
+ }
128
+ }
129
+ return types;
130
+ }
131
+
132
+ //parameterType.length == this.classes.length
133
+ //Note: right now we don't do any clever mapping, we
134
+ //only use Java's sub type relation: isAssigableFrom
135
+ private boolean areArgumentsConvertibleTo(Class<?>[] parameterTypes) {
136
+ for (int i=0; i < parameterTypes.length; i++) {
137
+ Class<?> typei = parameterTypes[i];
138
+ if (this.classes[i] == null) {
139
+ if (typei.isPrimitive()) {
140
+ //Can't pass null as primitive
141
+ return false;
142
+ }
143
+ continue; //can always pass null (unless primitive)
144
+ }
145
+ if (!typei.isAssignableFrom(this.classes[i])) {
146
+ return false;
147
+ }
148
+ }
149
+ return true;
150
+ }
151
+
152
+ private Object invokeMethod(Object o, Method m) throws Exception {
153
+ List<?> a = this.arguments;
154
+ int size = a.size();
155
+ switch(size) {
156
+ case 0:
157
+ return m.invoke(o);
158
+ case 1:
159
+ return m.invoke(o,a.get(0));
160
+ case 2:
161
+ return m.invoke(o,a.get(0),a.get(1));
162
+ case 3:
163
+ return m.invoke(o,a.get(0),a.get(1),a.get(2));
164
+ case 4:
165
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3));
166
+ case 5:
167
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4));
168
+ case 6:
169
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5));
170
+ case 7:
171
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6));
172
+ case 8:
173
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7));
174
+ case 9:
175
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8));
176
+ case 10:
177
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9));
178
+ case 11:
179
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9),a.get(10));
180
+ case 12:
181
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9),a.get(10),a.get(11));
182
+ case 13:
183
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9),a.get(10),a.get(11),a.get(12));
184
+ case 14:
185
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9),a.get(10),a.get(11),a.get(12),a.get(13));
186
+ case 15:
187
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9),a.get(10),a.get(11),a.get(12),a.get(13),a.get(14));
188
+ case 16:
189
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9),a.get(10),a.get(11),a.get(12),a.get(13),a.get(14),a.get(15));
190
+ }
191
+ throw new UnsupportedOperationException("Method with more than 16 arguments are not supported");
192
+
193
+ }
194
+
195
+
196
+ @Override
197
+ public String getName() {
198
+ return "InvocationOp["+this.methodName+", arguments = " + this.arguments + "]";
199
+ }
200
+
201
+ }