testautoa 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +7 -7
- data/bin/calabash-android +8 -1
- data/bin/calabash-android-build.rb +1 -1
- data/bin/calabash-android-console.rb +4 -4
- data/bin/calabash-android-run.rb +2 -10
- data/bin/testautoa +461 -0
- data/calabash-android.gemspec +3 -1
- data/features-skeleton/support/app_life_cycle_hooks.rb +0 -1
- data/irbrc +3 -1
- data/lib/calabash-android/helpers.rb +45 -17
- data/lib/calabash-android/lib/TestServer.apk +0 -0
- data/lib/calabash-android/lib/unsign.jar +0 -0
- data/lib/calabash-android/operations.rb +150 -66
- data/lib/calabash-android/steps/list_steps.rb +1 -1
- data/lib/calabash-android/steps/time_picker_steps.rb +1 -1
- data/lib/calabash-android/touch_helpers.rb +9 -0
- data/lib/calabash-android/version.rb +1 -1
- data/lib/calabash-android/wait_helpers.rb +93 -0
- data/test-server/AndroidManifest.xml +2 -0
- data/test-server/build.xml +1 -0
- data/test-server/instrumentation-backend/.classpath +0 -1
- data/test-server/instrumentation-backend/AndroidManifest.xml +1 -1
- data/test-server/instrumentation-backend/antlr/UIQuery.g +48 -5
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Command.java +4 -3
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/FranklyResult.java +95 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Result.java +7 -1
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/HttpServer.java +14 -29
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/FinishOpenedActivities.java +19 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/GetOpenedActivities.java +31 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/GoBackToActivity.java +67 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/gestures/DragCoordinates.java +28 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/gestures/Swipe.java +11 -5
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/location/FakeGPSLocation.java +13 -10
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/LeftKey.java +24 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/RightKey.java +24 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/UpKey.java +24 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/version/Version.java +31 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/CalabashChromeClient.java +131 -36
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpBodyHtml.java +38 -18
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpHtml.java +38 -16
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/EnterTextByCssSelector.java +94 -66
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ExecuteAsyncJavascript.java +55 -33
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ExecuteJavascript.java +53 -31
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/JavaScriptOperation.java +44 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/PressByCssSelector.java +52 -27
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/QueryHelper.java +39 -32
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ScrollTo.java +56 -41
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetPropertyByCssSelector.java +50 -25
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetText.java +19 -22
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/CompletedFuture.java +40 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/InvocationOperation.java +222 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Operation.java +7 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/PropertyOperation.java +56 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Query.java +151 -43
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQuery.tokens +19 -12
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQueryResultVoid.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ViewMapper.java +41 -11
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryLexer.java +1010 -242
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryParser.java +406 -98
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/BeginsWithRelation.java +45 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/ComparisonOperator.java +54 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/ContainsRelation.java +41 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/EndsWithRelation.java +42 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/LikeRelation.java +79 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/PartialFutureList.java +100 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryAST.java +1 -1
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTClassName.java +54 -25
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTPredicate.java +147 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTPredicateRelation.java +5 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTWith.java +153 -89
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryDirection.java +12 -2
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryEvaluator.java +58 -141
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryUtils.java +162 -7
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryVisibility.java +32 -0
- metadata +130 -97
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Query.java +0 -24
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Touch.java +0 -44
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQuery.tokens +0 -10
- data/test-server/instrumentation-backend/tests/sh/calaba/instrumentationbackend/query/tests/UIQueryTest.java +0 -134
|
@@ -3,136 +3,200 @@ package sh.calaba.instrumentationbackend.query.ast;
|
|
|
3
3
|
import java.lang.reflect.Method;
|
|
4
4
|
import java.util.ArrayList;
|
|
5
5
|
import java.util.List;
|
|
6
|
+
import java.util.Map;
|
|
7
|
+
import java.util.concurrent.Callable;
|
|
8
|
+
import java.util.concurrent.Future;
|
|
6
9
|
|
|
7
10
|
import org.antlr.runtime.tree.CommonTree;
|
|
8
11
|
|
|
9
|
-
import sh.calaba.instrumentationbackend.
|
|
10
|
-
import sh.calaba.instrumentationbackend.query.antlr.UIQueryParser;
|
|
12
|
+
import sh.calaba.instrumentationbackend.actions.webview.QueryHelper;
|
|
11
13
|
import android.view.View;
|
|
14
|
+
import android.webkit.WebView;
|
|
12
15
|
|
|
13
16
|
public class UIQueryASTWith implements UIQueryAST {
|
|
14
|
-
public final String propertyName;
|
|
17
|
+
public final String propertyName;
|
|
15
18
|
public final Object value;
|
|
16
|
-
|
|
17
|
-
public UIQueryASTWith(String property, Object value)
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
public UIQueryASTWith(String property, Object value) {
|
|
21
|
+
if (property == null) {
|
|
22
|
+
throw new IllegalArgumentException(
|
|
23
|
+
"Cannot instantiate Filter with null property name");
|
|
24
|
+
}
|
|
20
25
|
this.propertyName = property;
|
|
21
26
|
this.value = value;
|
|
22
27
|
}
|
|
23
28
|
|
|
24
|
-
@SuppressWarnings({ "rawtypes", "unchecked"})
|
|
29
|
+
@SuppressWarnings({ "rawtypes", "unchecked" })
|
|
25
30
|
@Override
|
|
26
|
-
public List
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
Object
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
System.out.println(this.value.getClass());
|
|
51
|
-
System.out.println(value.toString().equals(this.value));
|
|
52
|
-
if (value == this.value || (value != null && value.equals(this.value)))
|
|
53
|
-
{
|
|
54
|
-
result.add(o);
|
|
55
|
-
}
|
|
56
|
-
else if (this.value instanceof String && this.value.equals(value.toString()))
|
|
57
|
-
{
|
|
58
|
-
result.add(o);
|
|
31
|
+
public List evaluateWithViews(final List inputViews, final UIQueryDirection direction,
|
|
32
|
+
final UIQueryVisibility visibility) {
|
|
33
|
+
|
|
34
|
+
List queryResult = (List) UIQueryUtils.evaluateSyncInMainThread(new Callable() {
|
|
35
|
+
|
|
36
|
+
@Override
|
|
37
|
+
public Object call() throws Exception {
|
|
38
|
+
List futureResult = new ArrayList(8);
|
|
39
|
+
|
|
40
|
+
for (int i = 0; i < inputViews.size(); i++) {
|
|
41
|
+
Object o = inputViews.get(i);
|
|
42
|
+
|
|
43
|
+
if (o instanceof WebView) {
|
|
44
|
+
Future webResult = evaluateForWebView((WebView) o);
|
|
45
|
+
if (webResult != null) {
|
|
46
|
+
futureResult.add(webResult);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else if (o instanceof Map) {
|
|
50
|
+
Map result = evaluateForMap((Map) o);
|
|
51
|
+
if (result != null) {
|
|
52
|
+
futureResult.add(result);
|
|
53
|
+
}
|
|
54
|
+
|
|
59
55
|
}
|
|
60
56
|
else {
|
|
61
|
-
|
|
57
|
+
Object result = evaluateForObject(o, i);
|
|
58
|
+
if (result != null) {
|
|
59
|
+
futureResult.add(result);
|
|
60
|
+
}
|
|
62
61
|
}
|
|
63
|
-
|
|
64
|
-
}
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
List visibilityFilteredResults = visibility.evaluateWithViews(futureResult, direction,
|
|
65
|
+
visibility);
|
|
66
|
+
return new PartialFutureList(visibilityFilteredResults);
|
|
65
67
|
}
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
+
});
|
|
68
69
|
|
|
70
|
+
List processedResult = new ArrayList(queryResult.size());
|
|
71
|
+
for (Object o : queryResult) {
|
|
72
|
+
if (o instanceof Map) {
|
|
73
|
+
Map m = (Map) o;
|
|
74
|
+
if (m.containsKey("result")) {
|
|
75
|
+
processedResult.addAll(UIQueryUtils.mapWebViewJsonResponse((String) m.get("result"),(WebView) m.get("webView")));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
processedResult.add(m);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
processedResult.add(o);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return processedResult;
|
|
69
87
|
|
|
70
|
-
|
|
88
|
+
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@SuppressWarnings("rawtypes")
|
|
93
|
+
private Map evaluateForMap(Map map) {
|
|
94
|
+
if (map.containsKey(this.propertyName)) {
|
|
95
|
+
Object value = map.get(this.propertyName);
|
|
96
|
+
if (value == this.value || (value != null && value.equals(this.value))) {
|
|
97
|
+
return map;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private Object evaluateForObject(Object o, int index) {
|
|
104
|
+
if (this.propertyName.equals("id") && hasId(o, this.value)) {
|
|
105
|
+
return o;
|
|
106
|
+
} else if (this.propertyName.equals("marked")
|
|
107
|
+
&& isMarked(o, this.value)) {
|
|
108
|
+
return o;
|
|
109
|
+
} else if (this.propertyName.equals("index")
|
|
110
|
+
&& this.value.equals(index)) {
|
|
111
|
+
return o;
|
|
112
|
+
} else {
|
|
113
|
+
|
|
114
|
+
Method propertyAccessor = UIQueryUtils.hasProperty(o,
|
|
115
|
+
this.propertyName);
|
|
116
|
+
if (propertyAccessor != null) {
|
|
117
|
+
Object value = UIQueryUtils.getProperty(o, propertyAccessor);
|
|
118
|
+
|
|
119
|
+
if (value == this.value
|
|
120
|
+
|| (value != null && value.equals(this.value))) {
|
|
121
|
+
return o;
|
|
122
|
+
} else if (this.value instanceof String
|
|
123
|
+
&& this.value.equals(value.toString())) {
|
|
124
|
+
return o;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@SuppressWarnings({ "rawtypes" })
|
|
133
|
+
private Future evaluateForWebView(WebView o) {
|
|
134
|
+
if (!(this.value instanceof String)) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
return QueryHelper.executeAsyncJavascriptInWebviews(o,
|
|
138
|
+
"calabash.js", (String) this.value,this.propertyName);
|
|
139
|
+
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private boolean hasId(Object o, Object expectedValue) {
|
|
143
|
+
if (!(o instanceof View)) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
if (!(expectedValue instanceof String)) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
View view = (View) o;
|
|
150
|
+
String expected = (String) expectedValue;
|
|
151
|
+
String id = UIQueryUtils.getId(view);
|
|
152
|
+
return (id != null && id.equals(expected));
|
|
71
153
|
}
|
|
72
154
|
|
|
73
155
|
private boolean isMarked(Object o, Object expectedValue) {
|
|
74
|
-
if (!
|
|
75
|
-
|
|
156
|
+
if (!(o instanceof View)) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
if (!(expectedValue instanceof String)) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
76
162
|
View view = (View) o;
|
|
77
163
|
String expected = (String) expectedValue;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
.getResources().getResourceEntryName(view.getId());
|
|
81
|
-
|
|
82
|
-
if (id != null && id.equals(expected)) {
|
|
164
|
+
|
|
165
|
+
if (hasId(o, expectedValue)) {
|
|
83
166
|
return true;
|
|
84
167
|
}
|
|
85
|
-
|
|
86
|
-
CharSequence contentDescription = view.getContentDescription();
|
|
87
|
-
if (contentDescription != null
|
|
88
|
-
|
|
168
|
+
|
|
169
|
+
CharSequence contentDescription = view.getContentDescription();
|
|
170
|
+
if (contentDescription != null
|
|
171
|
+
&& contentDescription.toString().equals(expected)) {
|
|
89
172
|
return true;
|
|
90
173
|
}
|
|
91
|
-
|
|
174
|
+
|
|
92
175
|
try {
|
|
93
176
|
Method getTextM = view.getClass().getMethod("getText");
|
|
94
177
|
Object text = getTextM.invoke(view);
|
|
95
|
-
if (text != null && text.toString().equals(expected))
|
|
96
|
-
{
|
|
178
|
+
if (text != null && text.toString().equals(expected)) {
|
|
97
179
|
return true;
|
|
98
180
|
}
|
|
99
|
-
|
|
100
|
-
} catch (Exception e) {
|
|
101
|
-
|
|
181
|
+
|
|
182
|
+
} catch (Exception e) {
|
|
183
|
+
}
|
|
184
|
+
|
|
102
185
|
return false;
|
|
186
|
+
|
|
103
187
|
}
|
|
104
188
|
|
|
105
189
|
public static UIQueryASTWith fromAST(CommonTree step) {
|
|
106
190
|
CommonTree prop = (CommonTree) step.getChild(0);
|
|
107
191
|
CommonTree val = (CommonTree) step.getChild(1);
|
|
108
192
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
case UIQueryParser.STRING: {
|
|
112
|
-
String textWithPings = val.getText();
|
|
113
|
-
String text = textWithPings.substring(1, textWithPings.length()-1);
|
|
114
|
-
return new UIQueryASTWith(prop.getText(), text);
|
|
115
|
-
}
|
|
116
|
-
case UIQueryParser.INT:
|
|
117
|
-
return new UIQueryASTWith(prop.getText(), Integer.parseInt(val.getText(), 10));
|
|
118
|
-
case UIQueryParser.BOOL:{
|
|
119
|
-
String text = val.getText();
|
|
120
|
-
return new UIQueryASTWith(prop.getText(), Boolean.parseBoolean(text));
|
|
121
|
-
}
|
|
122
|
-
case UIQueryParser.NIL:
|
|
123
|
-
return new UIQueryASTWith(prop.getText(), null);
|
|
124
|
-
|
|
125
|
-
default:
|
|
126
|
-
throw new IllegalArgumentException("Unable to parse value type:" + val.getType()+ " text "+val.getText());
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
|
|
193
|
+
Object parsedVal = UIQueryUtils.parseValue(val);
|
|
194
|
+
return new UIQueryASTWith(prop.getText(), parsedVal);
|
|
130
195
|
}
|
|
131
|
-
|
|
132
|
-
|
|
196
|
+
|
|
133
197
|
@Override
|
|
134
198
|
public String toString() {
|
|
135
|
-
return "With["+this.propertyName+":"+this.value+"]";
|
|
199
|
+
return "With[" + this.propertyName + ":" + this.value + "]";
|
|
136
200
|
}
|
|
137
|
-
|
|
201
|
+
|
|
138
202
|
}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
package sh.calaba.instrumentationbackend.query.ast;
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import java.util.List;
|
|
4
|
+
|
|
5
|
+
public enum UIQueryDirection implements UIQueryAST {
|
|
6
|
+
DESCENDANT, CHILD, PARENT, SIBLING;
|
|
7
|
+
|
|
8
|
+
@SuppressWarnings("rawtypes")
|
|
9
|
+
@Override
|
|
10
|
+
public List evaluateWithViews(List inputViews, UIQueryDirection direction,
|
|
11
|
+
UIQueryVisibility visibility) {
|
|
12
|
+
//Never called. Not so pretty, I know.
|
|
13
|
+
throw new UnsupportedOperationException("This method should never be called");
|
|
14
|
+
}
|
|
5
15
|
}
|
|
@@ -1,122 +1,72 @@
|
|
|
1
1
|
package sh.calaba.instrumentationbackend.query.ast;
|
|
2
2
|
|
|
3
|
-
import java.io.IOException;
|
|
4
|
-
import java.lang.reflect.Method;
|
|
5
3
|
import java.util.ArrayList;
|
|
6
|
-
import java.util.Collections;
|
|
7
|
-
import java.util.HashMap;
|
|
8
4
|
import java.util.List;
|
|
9
|
-
import java.util.Map;
|
|
10
5
|
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import org.antlr.runtime.tree.CommonTree;
|
|
15
|
-
|
|
16
|
-
import sh.calaba.instrumentationbackend.query.antlr.UIQueryLexer;
|
|
17
|
-
import sh.calaba.instrumentationbackend.query.antlr.UIQueryParser;
|
|
18
|
-
import sh.calaba.org.codehaus.jackson.map.ObjectMapper;
|
|
6
|
+
import sh.calaba.instrumentationbackend.query.Operation;
|
|
7
|
+
import sh.calaba.instrumentationbackend.query.UIQueryResultVoid;
|
|
8
|
+
import sh.calaba.instrumentationbackend.query.ViewMapper;
|
|
19
9
|
|
|
20
10
|
public class UIQueryEvaluator {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
|
|
12
|
+
@SuppressWarnings({ "rawtypes" })
|
|
13
|
+
public static List evaluateQueryWithOptions(List<UIQueryAST> query, List inputViews,
|
|
14
|
+
List<Operation> operations) {
|
|
24
15
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
16
|
+
long before = System.currentTimeMillis();
|
|
17
|
+
|
|
18
|
+
List views = evaluateQueryForPath(query, inputViews);
|
|
19
|
+
|
|
20
|
+
long after = System.currentTimeMillis();
|
|
21
|
+
String action = "EvaluateQuery";
|
|
22
|
+
System.out.println(action+ " took: "+ (after-before) + "ms");
|
|
23
|
+
|
|
24
|
+
before = System.currentTimeMillis();
|
|
25
|
+
|
|
26
|
+
List result = applyOperations(views, operations);
|
|
27
|
+
|
|
28
|
+
after = System.currentTimeMillis();
|
|
29
|
+
action = "ApplyOperations";
|
|
30
|
+
System.out.println(action+ " took: "+ (after-before) + "ms");
|
|
31
|
+
|
|
32
|
+
before = System.currentTimeMillis();
|
|
33
|
+
|
|
34
|
+
List finalResult = mapViews(result);
|
|
35
|
+
|
|
36
|
+
after = System.currentTimeMillis();
|
|
37
|
+
action = "MapViews";
|
|
38
|
+
return finalResult;
|
|
39
|
+
}
|
|
42
40
|
|
|
43
|
-
@SuppressWarnings({ "rawtypes", "unchecked" })
|
|
44
|
-
public Object asJSON(String methodName, Object receiver,String errorMessage) {
|
|
45
|
-
ObjectMapper mapper = new ObjectMapper();
|
|
46
41
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
map.put("receiverString",receiver.toString());
|
|
53
|
-
return mapper.writeValueAsString(map);
|
|
54
|
-
} catch (IOException e) {
|
|
55
|
-
throw new RuntimeException("Could not convert result to json",e);
|
|
56
|
-
}
|
|
42
|
+
@SuppressWarnings({ "unchecked", "rawtypes" })
|
|
43
|
+
public static List mapViews(List result) {
|
|
44
|
+
List finalResult = new ArrayList(result.size());
|
|
45
|
+
for (Object o : result) {
|
|
46
|
+
finalResult.add(ViewMapper.mapView(o));
|
|
57
47
|
}
|
|
48
|
+
return finalResult;
|
|
58
49
|
}
|
|
59
50
|
|
|
60
|
-
@SuppressWarnings({ "rawtypes" })
|
|
61
|
-
public static List evaluateQuery(String query, List inputViews) {
|
|
62
|
-
return evaluateQueryForPath(parseQuery(query), inputViews);
|
|
63
|
-
}
|
|
64
51
|
|
|
65
52
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
|
66
|
-
public static List
|
|
67
|
-
List options) {
|
|
68
|
-
List views = evaluateQueryForPath(parseQuery(query), inputViews);
|
|
69
|
-
|
|
53
|
+
public static List applyOperations(List views, List<Operation> operations) {
|
|
70
54
|
List result = views;
|
|
71
|
-
for
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
for (Object o : result) {
|
|
55
|
+
for(Operation op : operations) {
|
|
56
|
+
List nextResult = new ArrayList(result.size());
|
|
57
|
+
for (Object obj : result) {
|
|
75
58
|
try {
|
|
76
|
-
|
|
77
|
-
if (m != null) {
|
|
78
|
-
nextResult.add(m.invoke(o));
|
|
79
|
-
}
|
|
80
|
-
else
|
|
81
|
-
{
|
|
82
|
-
nextResult.add(UIQueryResultVoid.instance.asJSON(propertyName,o,"NO accessor for "+propertyName));
|
|
83
|
-
}
|
|
84
|
-
|
|
59
|
+
nextResult.add(op.apply(obj));
|
|
85
60
|
} catch (Exception e) {
|
|
86
|
-
|
|
87
|
-
nextResult.add(UIQueryResultVoid.instance.
|
|
88
|
-
}
|
|
61
|
+
e.printStackTrace();
|
|
62
|
+
nextResult.add(UIQueryResultVoid.instance.asMap(op.getName(), obj, e.getMessage()));
|
|
63
|
+
}
|
|
89
64
|
}
|
|
90
65
|
result = nextResult;
|
|
91
66
|
}
|
|
92
67
|
return result;
|
|
93
|
-
|
|
94
68
|
}
|
|
95
69
|
|
|
96
|
-
@SuppressWarnings("unchecked")
|
|
97
|
-
public static List<UIQueryAST> parseQuery(String query) {
|
|
98
|
-
UIQueryLexer lexer = new UIQueryLexer(new ANTLRStringStream(query));
|
|
99
|
-
UIQueryParser parser = new UIQueryParser(new CommonTokenStream(lexer));
|
|
100
|
-
|
|
101
|
-
UIQueryParser.query_return q;
|
|
102
|
-
try {
|
|
103
|
-
q = parser.query();
|
|
104
|
-
} catch (RecognitionException e) {
|
|
105
|
-
// TODO Auto-generated catch block
|
|
106
|
-
throw new InvalidUIQueryException(e.getMessage());
|
|
107
|
-
}
|
|
108
|
-
if (q == null) {
|
|
109
|
-
throw new InvalidUIQueryException(query);
|
|
110
|
-
}
|
|
111
|
-
CommonTree rootNode = (CommonTree) q.getTree();
|
|
112
|
-
List<CommonTree> queryPath = rootNode.getChildren();
|
|
113
|
-
|
|
114
|
-
if (queryPath == null || queryPath.isEmpty()) {
|
|
115
|
-
queryPath = Collections.singletonList(rootNode);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return mapUIQueryFromAstNodes(queryPath);
|
|
119
|
-
}
|
|
120
70
|
|
|
121
71
|
@SuppressWarnings("rawtypes")
|
|
122
72
|
private static List evaluateQueryForPath(List<UIQueryAST> queryPath,
|
|
@@ -124,59 +74,26 @@ public class UIQueryEvaluator {
|
|
|
124
74
|
|
|
125
75
|
List currentResult = inputViews;
|
|
126
76
|
UIQueryDirection currentDirection = UIQueryDirection.DESCENDANT;
|
|
77
|
+
UIQueryVisibility currentVisibility = UIQueryVisibility.VISIBLE;
|
|
78
|
+
|
|
127
79
|
for (UIQueryAST step : queryPath) {
|
|
128
|
-
if (
|
|
129
|
-
currentDirection =
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
80
|
+
if (step instanceof UIQueryDirection) {
|
|
81
|
+
currentDirection = (UIQueryDirection) step;
|
|
82
|
+
}
|
|
83
|
+
else if (step instanceof UIQueryVisibility) {
|
|
84
|
+
currentVisibility = (UIQueryVisibility) step;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
currentResult = step.evaluateWithViews(currentResult, currentDirection,currentVisibility);
|
|
133
88
|
}
|
|
134
89
|
|
|
135
90
|
}
|
|
136
91
|
return currentResult;
|
|
137
92
|
}
|
|
138
|
-
|
|
139
|
-
public static UIQueryDirection directionFromAst(UIQueryAST step) {
|
|
140
|
-
// TODO Auto-generated method stub
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
93
|
+
|
|
143
94
|
|
|
144
95
|
public static boolean isDirection(UIQueryAST step) {
|
|
145
|
-
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
public static List<UIQueryAST> mapUIQueryFromAstNodes(List<CommonTree> nodes) {
|
|
150
|
-
List<UIQueryAST> mapped = new ArrayList<UIQueryAST>(nodes.size());
|
|
151
|
-
for (CommonTree t : nodes) {
|
|
152
|
-
mapped.add(uiQueryFromAst(t));
|
|
153
|
-
}
|
|
154
|
-
return mapped;
|
|
96
|
+
return step instanceof UIQueryDirection;
|
|
155
97
|
}
|
|
156
|
-
|
|
157
|
-
public static UIQueryAST uiQueryFromAst(CommonTree step) {
|
|
158
|
-
String stepType = UIQueryParser.tokenNames[step.getType()];
|
|
159
|
-
switch (step.getType()) {
|
|
160
|
-
case UIQueryParser.QUALIFIED_NAME:
|
|
161
|
-
try {
|
|
162
|
-
return new UIQueryASTClassName(Class.forName(step.getText()));
|
|
163
|
-
} catch (ClassNotFoundException e) {
|
|
164
|
-
// TODO Auto-generated catch block
|
|
165
|
-
throw new InvalidUIQueryException("Qualified class name: "
|
|
166
|
-
+ step.getText() + " not found. (" + e.getMessage()
|
|
167
|
-
+ ")");
|
|
168
|
-
}
|
|
169
|
-
case UIQueryParser.NAME:
|
|
170
|
-
return new UIQueryASTClassName(step.getText());
|
|
171
|
-
|
|
172
|
-
case UIQueryParser.FILTER_COLON:
|
|
173
|
-
return UIQueryASTWith.fromAST(step);
|
|
174
|
-
default:
|
|
175
|
-
throw new InvalidUIQueryException("Unknown query: " + stepType
|
|
176
|
-
+ " with text: " + step.getText());
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
|
|
98
|
+
|
|
182
99
|
}
|