calabash-android 0.4.0.pre1 → 0.4.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/calabash-android-build.rb +6 -0
- data/bin/calabash-android-setup.rb +2 -3
- data/lib/calabash-android/canned_steps.md +1 -1
- data/lib/calabash-android/helpers.rb +35 -2
- data/lib/calabash-android/lib/TestServer.apk +0 -0
- data/lib/calabash-android/operations.rb +13 -6
- data/lib/calabash-android/version.rb +1 -1
- data/test-server/instrumentation-backend/.classpath +2 -1
- data/test-server/instrumentation-backend/antlr.sh +2 -0
- data/test-server/instrumentation-backend/antlr/UIQuery.g +70 -0
- data/test-server/instrumentation-backend/antlr/UIQuery.tokens +12 -0
- data/test-server/instrumentation-backend/build-libs/antlr-3.4-complete.jar +0 -0
- data/test-server/instrumentation-backend/build-libs/junit.jar +0 -0
- data/test-server/instrumentation-backend/build.xml +56 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/ANTLRFileStream.java +78 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/ANTLRInputStream.java +70 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/ANTLRReaderStream.java +95 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/ANTLRStringStream.java +230 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/BaseRecognizer.java +894 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/BitSet.java +325 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/BufferedTokenStream.java +272 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/CharStream.java +57 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/CharStreamState.java +45 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/ClassicToken.java +141 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/CommonToken.java +191 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/CommonTokenStream.java +153 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/DFA.java +250 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/EarlyExitException.java +41 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/FailedPredicateException.java +54 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/IntStream.java +122 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/LegacyCommonTokenStream.java +394 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/Lexer.java +340 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedNotSetException.java +41 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedRangeException.java +45 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedSetException.java +44 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedTokenException.java +45 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedTreeNodeException.java +49 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/MissingTokenException.java +56 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/NoViableAltException.java +57 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/Parser.java +98 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/ParserRuleReturnScope.java +52 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/RecognitionException.java +180 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/RecognizerSharedState.java +144 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/RuleReturnScope.java +42 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/SerializedGrammar.java +204 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/Token.java +92 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/TokenRewriteStream.java +569 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/TokenSource.java +54 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/TokenStream.java +75 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/UnbufferedTokenStream.java +82 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/UnwantedTokenException.java +53 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/BlankDebugEventListener.java +77 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugEventHub.java +292 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugEventListener.java +323 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugEventRepeater.java +88 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugEventSocketProxy.java +358 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugParser.java +101 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugTokenStream.java +156 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugTreeAdaptor.java +250 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugTreeNodeStream.java +155 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugTreeParser.java +112 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/ParseTreeBuilder.java +109 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/Profiler.java +772 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/RemoteDebugEventSocketListener.java +541 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/TraceDebugEventListener.java +108 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/Tracer.java +69 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/DoubleKeyMap.java +62 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/FastQueue.java +100 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/IntArray.java +87 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/LookaheadStream.java +161 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/Stats.java +189 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/BaseTree.java +349 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/BaseTreeAdaptor.java +279 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/BufferedTreeNodeStream.java +489 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/CommonErrorNode.java +108 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/CommonTree.java +185 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/CommonTreeAdaptor.java +168 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/CommonTreeNodeStream.java +171 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/ParseTree.java +119 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteCardinalityException.java +47 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteEarlyExitException.java +39 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteEmptyStreamException.java +35 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteRuleElementStream.java +210 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteRuleNodeStream.java +70 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteRuleSubtreeStream.java +86 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteRuleTokenStream.java +76 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/Tree.java +127 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeAdaptor.java +263 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeFilter.java +135 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeIterator.java +132 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeNodeStream.java +106 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeParser.java +169 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreePatternLexer.java +135 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreePatternParser.java +154 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeRewriter.java +124 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeRuleReturnScope.java +41 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeVisitor.java +69 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeVisitorAction.java +47 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeWizard.java +531 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/ClearAppData.java +22 -7
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/InstrumentationBackend.java +4 -4
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Result.java +0 -1
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/HttpServer.java +161 -129
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/SetActivityOrientation.java +5 -7
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/GetViewProperty.java +1 -7
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Query.java +70 -61
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQuery.tokens +12 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ViewMapper.java +63 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQuery.tokens +10 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryLexer.java +945 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryParser.java +463 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/InvalidUIQueryException.java +10 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryAST.java +8 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTClassName.java +115 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTWith.java +157 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryDirection.java +5 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryEvaluator.java +205 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryUtils.java +135 -0
- data/test-server/instrumentation-backend/tests/sh/calaba/instrumentationbackend/query/tests/UIQueryTest.java +134 -0
- metadata +106 -3
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/SetOrientation.java +0 -39
@@ -0,0 +1,115 @@
|
|
1
|
+
package sh.calaba.instrumentationbackend.query.ast;
|
2
|
+
|
3
|
+
import java.util.ArrayList;
|
4
|
+
import java.util.List;
|
5
|
+
|
6
|
+
public class UIQueryASTClassName implements UIQueryAST {
|
7
|
+
public final String simpleClassName;
|
8
|
+
@SuppressWarnings("rawtypes")
|
9
|
+
public final Class qualifiedClassName;
|
10
|
+
|
11
|
+
public UIQueryASTClassName(String simpleClassName)
|
12
|
+
{
|
13
|
+
if (simpleClassName == null) {throw new IllegalArgumentException("Cannot instantiate with null class");}
|
14
|
+
this.simpleClassName = simpleClassName;
|
15
|
+
this.qualifiedClassName = null;
|
16
|
+
}
|
17
|
+
|
18
|
+
@SuppressWarnings("rawtypes")
|
19
|
+
public UIQueryASTClassName(Class qualifiedClassName)
|
20
|
+
{
|
21
|
+
if (qualifiedClassName == null) {throw new IllegalArgumentException("Cannot instantiate with null class");}
|
22
|
+
this.qualifiedClassName = qualifiedClassName;
|
23
|
+
this.simpleClassName = null;
|
24
|
+
|
25
|
+
}
|
26
|
+
|
27
|
+
@SuppressWarnings({ "rawtypes"})
|
28
|
+
@Override
|
29
|
+
public List evaluateWithViewsAndDirection(List inputViews,
|
30
|
+
UIQueryDirection direction) {
|
31
|
+
// TODO Auto-generated method stub
|
32
|
+
|
33
|
+
List result = new ArrayList(8);
|
34
|
+
for (Object o : inputViews)
|
35
|
+
{
|
36
|
+
switch(direction) {
|
37
|
+
case DESCENDANT:
|
38
|
+
addDecendantMatchesToResult(o,result);
|
39
|
+
break;
|
40
|
+
case CHILD:
|
41
|
+
addChildMatchesToResult(o,result);
|
42
|
+
break;
|
43
|
+
case PARENT:
|
44
|
+
addParentMatchesToResult(o,result);
|
45
|
+
break;
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
}
|
50
|
+
|
51
|
+
|
52
|
+
return result;
|
53
|
+
}
|
54
|
+
|
55
|
+
@SuppressWarnings("rawtypes")
|
56
|
+
private void addParentMatchesToResult(Object o, List result) {
|
57
|
+
// TODO Auto-generated method stub
|
58
|
+
throw new UnsupportedOperationException();
|
59
|
+
}
|
60
|
+
|
61
|
+
@SuppressWarnings({ "rawtypes", "unchecked" })
|
62
|
+
private void addChildMatchesToResult(Object o, List result) {
|
63
|
+
for (Object child : UIQueryUtils.subviews(o))
|
64
|
+
{
|
65
|
+
if (match(child))
|
66
|
+
{
|
67
|
+
result.add(child);
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
@SuppressWarnings({ "unchecked", "rawtypes" })
|
73
|
+
private void addDecendantMatchesToResult(Object o, List result) {
|
74
|
+
if (match(o))
|
75
|
+
{
|
76
|
+
result.add(o);
|
77
|
+
}
|
78
|
+
|
79
|
+
for (Object child : UIQueryUtils.subviews(o))
|
80
|
+
{
|
81
|
+
addDecendantMatchesToResult(child, result);
|
82
|
+
}
|
83
|
+
|
84
|
+
}
|
85
|
+
|
86
|
+
private boolean match(Object o)
|
87
|
+
{
|
88
|
+
return matchSimpleClassName(o,this.simpleClassName) ||
|
89
|
+
matchQualifiedClassName(o,this.qualifiedClassName);
|
90
|
+
}
|
91
|
+
|
92
|
+
@SuppressWarnings({ "rawtypes", "unchecked" })
|
93
|
+
public static boolean matchQualifiedClassName(Object o, Class qualifiedClassName) {
|
94
|
+
return qualifiedClassName != null && qualifiedClassName.isAssignableFrom(o.getClass());
|
95
|
+
}
|
96
|
+
|
97
|
+
public static boolean matchSimpleClassName(Object o, String simpleClassName) {
|
98
|
+
// TODO Auto-generated method stub
|
99
|
+
return simpleClassName != null && simpleClassName.equalsIgnoreCase(o.getClass().getSimpleName());
|
100
|
+
}
|
101
|
+
|
102
|
+
public String toString() {
|
103
|
+
if (this.simpleClassName != null)
|
104
|
+
{
|
105
|
+
return "Class["+this.simpleClassName+"]";
|
106
|
+
}
|
107
|
+
else
|
108
|
+
{
|
109
|
+
return "Class["+this.qualifiedClassName+"]";
|
110
|
+
}
|
111
|
+
|
112
|
+
}
|
113
|
+
|
114
|
+
|
115
|
+
}
|
@@ -0,0 +1,157 @@
|
|
1
|
+
package sh.calaba.instrumentationbackend.query.ast;
|
2
|
+
|
3
|
+
import java.lang.reflect.Method;
|
4
|
+
import java.util.ArrayList;
|
5
|
+
import java.util.List;
|
6
|
+
|
7
|
+
import org.antlr.runtime.tree.CommonTree;
|
8
|
+
|
9
|
+
import sh.calaba.instrumentationbackend.InstrumentationBackend;
|
10
|
+
import sh.calaba.instrumentationbackend.query.antlr.UIQueryParser;
|
11
|
+
import android.content.res.Resources.NotFoundException;
|
12
|
+
import android.view.View;
|
13
|
+
|
14
|
+
public class UIQueryASTWith implements UIQueryAST {
|
15
|
+
public final String propertyName;
|
16
|
+
public final Object value;
|
17
|
+
|
18
|
+
public UIQueryASTWith(String property, Object value)
|
19
|
+
{
|
20
|
+
if (property == null) {throw new IllegalArgumentException("Cannot instantiate Filter with null property name");}
|
21
|
+
this.propertyName = property;
|
22
|
+
this.value = value;
|
23
|
+
}
|
24
|
+
|
25
|
+
@SuppressWarnings({ "rawtypes", "unchecked"})
|
26
|
+
@Override
|
27
|
+
public List evaluateWithViewsAndDirection(List inputViews,
|
28
|
+
UIQueryDirection direction) {
|
29
|
+
List result = new ArrayList(8);
|
30
|
+
|
31
|
+
for (int i=0;i<inputViews.size();i++)
|
32
|
+
{
|
33
|
+
Object o = inputViews.get(i);
|
34
|
+
if (this.propertyName.equals("id") && hasId(o,this.value))
|
35
|
+
{
|
36
|
+
result.add(o);
|
37
|
+
}
|
38
|
+
else if (this.propertyName.equals("marked") && isMarked(o,this.value))
|
39
|
+
{
|
40
|
+
result.add(o);
|
41
|
+
}
|
42
|
+
else if (this.propertyName.equals("index") && this.value.equals(i))
|
43
|
+
{
|
44
|
+
result.add(o);
|
45
|
+
}
|
46
|
+
else
|
47
|
+
{
|
48
|
+
|
49
|
+
Method propertyAccessor = UIQueryUtils.hasProperty(o, this.propertyName);
|
50
|
+
if (propertyAccessor != null)
|
51
|
+
{
|
52
|
+
Object value = UIQueryUtils.getProperty(o, propertyAccessor);
|
53
|
+
|
54
|
+
if (value == this.value || (value != null && value.equals(this.value)))
|
55
|
+
{
|
56
|
+
result.add(o);
|
57
|
+
}
|
58
|
+
else if (this.value instanceof String && this.value.equals(value.toString()))
|
59
|
+
{
|
60
|
+
result.add(o);
|
61
|
+
}
|
62
|
+
|
63
|
+
|
64
|
+
}
|
65
|
+
|
66
|
+
}
|
67
|
+
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
return result;
|
72
|
+
}
|
73
|
+
|
74
|
+
private boolean hasId(Object o, Object expectedValue) {
|
75
|
+
if (! (o instanceof View)) { return false; }
|
76
|
+
if (! (expectedValue instanceof String)) { return false; }
|
77
|
+
View view = (View) o;
|
78
|
+
String expected = (String) expectedValue;
|
79
|
+
|
80
|
+
try {
|
81
|
+
String id = InstrumentationBackend.solo.getCurrentActivity()
|
82
|
+
.getResources().getResourceEntryName(view.getId());
|
83
|
+
|
84
|
+
if (id != null && id.equals(expected)) {
|
85
|
+
return true;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
catch (NotFoundException e) {}
|
89
|
+
return false;
|
90
|
+
}
|
91
|
+
|
92
|
+
private boolean isMarked(Object o, Object expectedValue) {
|
93
|
+
if (! (o instanceof View)) { return false; }
|
94
|
+
if (! (expectedValue instanceof String)) { return false; }
|
95
|
+
View view = (View) o;
|
96
|
+
String expected = (String) expectedValue;
|
97
|
+
|
98
|
+
if (hasId(o, expectedValue))
|
99
|
+
{
|
100
|
+
return true;
|
101
|
+
}
|
102
|
+
|
103
|
+
|
104
|
+
CharSequence contentDescription = view.getContentDescription();
|
105
|
+
if (contentDescription != null && contentDescription.toString().equals(expected))
|
106
|
+
{
|
107
|
+
return true;
|
108
|
+
}
|
109
|
+
|
110
|
+
try {
|
111
|
+
Method getTextM = view.getClass().getMethod("getText");
|
112
|
+
Object text = getTextM.invoke(view);
|
113
|
+
if (text != null && text.toString().equals(expected))
|
114
|
+
{
|
115
|
+
return true;
|
116
|
+
}
|
117
|
+
|
118
|
+
} catch (Exception e) {}
|
119
|
+
|
120
|
+
return false;
|
121
|
+
|
122
|
+
}
|
123
|
+
|
124
|
+
public static UIQueryASTWith fromAST(CommonTree step) {
|
125
|
+
CommonTree prop = (CommonTree) step.getChild(0);
|
126
|
+
CommonTree val = (CommonTree) step.getChild(1);
|
127
|
+
|
128
|
+
switch(val.getType())
|
129
|
+
{
|
130
|
+
case UIQueryParser.STRING: {
|
131
|
+
String textWithPings = val.getText();
|
132
|
+
String text = textWithPings.substring(1, textWithPings.length()-1);
|
133
|
+
return new UIQueryASTWith(prop.getText(), text);
|
134
|
+
}
|
135
|
+
case UIQueryParser.INT:
|
136
|
+
return new UIQueryASTWith(prop.getText(), Integer.parseInt(val.getText(), 10));
|
137
|
+
case UIQueryParser.BOOL:{
|
138
|
+
String text = val.getText();
|
139
|
+
return new UIQueryASTWith(prop.getText(), Boolean.parseBoolean(text));
|
140
|
+
}
|
141
|
+
case UIQueryParser.NIL:
|
142
|
+
return new UIQueryASTWith(prop.getText(), null);
|
143
|
+
|
144
|
+
default:
|
145
|
+
throw new IllegalArgumentException("Unable to parse value type:" + val.getType()+ " text "+val.getText());
|
146
|
+
|
147
|
+
}
|
148
|
+
|
149
|
+
}
|
150
|
+
|
151
|
+
|
152
|
+
@Override
|
153
|
+
public String toString() {
|
154
|
+
return "With["+this.propertyName+":"+this.value+"]";
|
155
|
+
}
|
156
|
+
|
157
|
+
}
|
@@ -0,0 +1,205 @@
|
|
1
|
+
package sh.calaba.instrumentationbackend.query.ast;
|
2
|
+
|
3
|
+
import java.io.IOException;
|
4
|
+
import java.lang.reflect.Method;
|
5
|
+
import java.util.ArrayList;
|
6
|
+
import java.util.Collections;
|
7
|
+
import java.util.HashMap;
|
8
|
+
import java.util.List;
|
9
|
+
import java.util.Map;
|
10
|
+
|
11
|
+
import org.antlr.runtime.ANTLRStringStream;
|
12
|
+
import org.antlr.runtime.CommonTokenStream;
|
13
|
+
import org.antlr.runtime.RecognitionException;
|
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;
|
19
|
+
|
20
|
+
public class UIQueryEvaluator {
|
21
|
+
|
22
|
+
private static class UIQueryResultVoid {
|
23
|
+
public static final UIQueryResultVoid instance = new UIQueryResultVoid();
|
24
|
+
|
25
|
+
private UIQueryResultVoid() {}
|
26
|
+
|
27
|
+
@SuppressWarnings({ "rawtypes", "unchecked" })
|
28
|
+
public String asJSON(String methodName, Object receiver) {
|
29
|
+
ObjectMapper mapper = new ObjectMapper();
|
30
|
+
|
31
|
+
try {
|
32
|
+
Map map = new HashMap();
|
33
|
+
map.put("error","Unable to invoke method");
|
34
|
+
map.put("methodName",methodName);
|
35
|
+
map.put("receiverClass", receiver.getClass().getName());
|
36
|
+
map.put("receiverString",receiver.toString());
|
37
|
+
return mapper.writeValueAsString(map);
|
38
|
+
} catch (IOException e) {
|
39
|
+
throw new RuntimeException("Could not convert result to json",e);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
@SuppressWarnings({ "rawtypes", "unchecked" })
|
44
|
+
public Object asJSON(String methodName, Object receiver,String errorMessage) {
|
45
|
+
ObjectMapper mapper = new ObjectMapper();
|
46
|
+
|
47
|
+
try {
|
48
|
+
Map map = new HashMap();
|
49
|
+
map.put("error",errorMessage);
|
50
|
+
map.put("methodName",methodName);
|
51
|
+
map.put("receiverClass", receiver.getClass().getName());
|
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
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
@SuppressWarnings({ "rawtypes" })
|
61
|
+
public static List evaluateQuery(String query, List inputViews) {
|
62
|
+
return evaluateQueryForPath(parseQuery(query), inputViews);
|
63
|
+
}
|
64
|
+
|
65
|
+
@SuppressWarnings({ "rawtypes", "unchecked" })
|
66
|
+
public static List evaluateQueryWithOptions(String query, List inputViews,
|
67
|
+
List options) {
|
68
|
+
|
69
|
+
long before = System.currentTimeMillis();
|
70
|
+
List views = evaluateQueryForPath(parseQuery(query), inputViews);
|
71
|
+
long after = System.currentTimeMillis();
|
72
|
+
String action = "EvaluateQueryNoOptions";
|
73
|
+
System.out.println(action+ " took: "+ (after-before) + "ms");
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
List result = views;
|
78
|
+
for (Object methodNameObj : options) {
|
79
|
+
String propertyName = (String) methodNameObj;
|
80
|
+
List nextResult = new ArrayList(views.size());
|
81
|
+
for (Object o : result) {
|
82
|
+
try {
|
83
|
+
|
84
|
+
before = System.currentTimeMillis();
|
85
|
+
|
86
|
+
Method m = UIQueryUtils.hasProperty(o, propertyName);
|
87
|
+
after = System.currentTimeMillis();
|
88
|
+
action = "HasProperty";
|
89
|
+
System.out.println(action+ " took: "+ (after-before) + "ms");
|
90
|
+
|
91
|
+
|
92
|
+
if (m != null) {
|
93
|
+
nextResult.add(m.invoke(o));
|
94
|
+
}
|
95
|
+
else
|
96
|
+
{
|
97
|
+
nextResult.add(UIQueryResultVoid.instance.asJSON(propertyName,o,"NO accessor for "+propertyName));
|
98
|
+
}
|
99
|
+
|
100
|
+
} catch (Exception e) {
|
101
|
+
System.out.println(e.getMessage());
|
102
|
+
nextResult.add(UIQueryResultVoid.instance.asJSON(propertyName,o));
|
103
|
+
}
|
104
|
+
}
|
105
|
+
result = nextResult;
|
106
|
+
}
|
107
|
+
return result;
|
108
|
+
|
109
|
+
}
|
110
|
+
|
111
|
+
@SuppressWarnings("unchecked")
|
112
|
+
public static List<UIQueryAST> parseQuery(String query) {
|
113
|
+
UIQueryLexer lexer = new UIQueryLexer(new ANTLRStringStream(query));
|
114
|
+
UIQueryParser parser = new UIQueryParser(new CommonTokenStream(lexer));
|
115
|
+
|
116
|
+
UIQueryParser.query_return q;
|
117
|
+
try {
|
118
|
+
q = parser.query();
|
119
|
+
} catch (RecognitionException e) {
|
120
|
+
// TODO Auto-generated catch block
|
121
|
+
throw new InvalidUIQueryException(e.getMessage());
|
122
|
+
}
|
123
|
+
if (q == null) {
|
124
|
+
throw new InvalidUIQueryException(query);
|
125
|
+
}
|
126
|
+
CommonTree rootNode = (CommonTree) q.getTree();
|
127
|
+
List<CommonTree> queryPath = rootNode.getChildren();
|
128
|
+
|
129
|
+
if (queryPath == null || queryPath.isEmpty()) {
|
130
|
+
queryPath = Collections.singletonList(rootNode);
|
131
|
+
}
|
132
|
+
|
133
|
+
return mapUIQueryFromAstNodes(queryPath);
|
134
|
+
}
|
135
|
+
|
136
|
+
@SuppressWarnings("rawtypes")
|
137
|
+
private static List evaluateQueryForPath(List<UIQueryAST> queryPath,
|
138
|
+
List inputViews) {
|
139
|
+
|
140
|
+
List currentResult = inputViews;
|
141
|
+
UIQueryDirection currentDirection = UIQueryDirection.DESCENDANT;
|
142
|
+
for (UIQueryAST step : queryPath) {
|
143
|
+
if (isDirection(step)) {
|
144
|
+
currentDirection = directionFromAst(step);
|
145
|
+
} else {
|
146
|
+
System.out.println(step);
|
147
|
+
long before = System.currentTimeMillis();
|
148
|
+
|
149
|
+
|
150
|
+
currentResult = step.evaluateWithViewsAndDirection(
|
151
|
+
currentResult, currentDirection);
|
152
|
+
long after = System.currentTimeMillis();
|
153
|
+
String action = "EvaluateQueryNoOptions" + step.toString();
|
154
|
+
System.out.println(action+ " took: "+ (after-before) + "ms");
|
155
|
+
|
156
|
+
}
|
157
|
+
|
158
|
+
}
|
159
|
+
return currentResult;
|
160
|
+
}
|
161
|
+
|
162
|
+
public static UIQueryDirection directionFromAst(UIQueryAST step) {
|
163
|
+
// TODO Auto-generated method stub
|
164
|
+
return null;
|
165
|
+
}
|
166
|
+
|
167
|
+
public static boolean isDirection(UIQueryAST step) {
|
168
|
+
// TODO Auto-generated method stub
|
169
|
+
return false;
|
170
|
+
}
|
171
|
+
|
172
|
+
public static List<UIQueryAST> mapUIQueryFromAstNodes(List<CommonTree> nodes) {
|
173
|
+
List<UIQueryAST> mapped = new ArrayList<UIQueryAST>(nodes.size());
|
174
|
+
for (CommonTree t : nodes) {
|
175
|
+
mapped.add(uiQueryFromAst(t));
|
176
|
+
}
|
177
|
+
return mapped;
|
178
|
+
}
|
179
|
+
|
180
|
+
public static UIQueryAST uiQueryFromAst(CommonTree step) {
|
181
|
+
String stepType = UIQueryParser.tokenNames[step.getType()];
|
182
|
+
switch (step.getType()) {
|
183
|
+
case UIQueryParser.QUALIFIED_NAME:
|
184
|
+
try {
|
185
|
+
return new UIQueryASTClassName(Class.forName(step.getText()));
|
186
|
+
} catch (ClassNotFoundException e) {
|
187
|
+
// TODO Auto-generated catch block
|
188
|
+
throw new InvalidUIQueryException("Qualified class name: "
|
189
|
+
+ step.getText() + " not found. (" + e.getMessage()
|
190
|
+
+ ")");
|
191
|
+
}
|
192
|
+
case UIQueryParser.NAME:
|
193
|
+
return new UIQueryASTClassName(step.getText());
|
194
|
+
|
195
|
+
case UIQueryParser.FILTER_COLON:
|
196
|
+
return UIQueryASTWith.fromAST(step);
|
197
|
+
default:
|
198
|
+
throw new InvalidUIQueryException("Unknown query: " + stepType
|
199
|
+
+ " with text: " + step.getText());
|
200
|
+
|
201
|
+
}
|
202
|
+
|
203
|
+
}
|
204
|
+
|
205
|
+
}
|