Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
S
super-appium
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
super-appium
Commits
c352e39c
Commit
c352e39c
authored
Aug 27, 2019
by
Administrator
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
8147e17a
Hide whitespace changes
Inline
Side-by-side
Showing
66 changed files
with
1946 additions
and
13 deletions
+1946
-13
Lists.java
...pium/src/main/java/com/virjar/superappium/util/Lists.java
+48
-0
XpathParser.java
...c/main/java/com/virjar/superappium/xpath/XpathParser.java
+14
-0
EvaluateException.java
...virjar/superappium/xpath/exception/EvaluateException.java
+22
-0
NoSuchAxisException.java
...rjar/superappium/xpath/exception/NoSuchAxisException.java
+7
-0
FunctionEnv.java
...va/com/virjar/superappium/xpath/function/FunctionEnv.java
+68
-0
NameAware.java
...java/com/virjar/superappium/xpath/function/NameAware.java
+5
-0
AxisFunction.java
.../virjar/superappium/xpath/function/axis/AxisFunction.java
+11
-0
FilterFunction.java
...jar/superappium/xpath/function/filter/FilterFunction.java
+11
-0
SelectFunction.java
...jar/superappium/xpath/function/select/SelectFunction.java
+12
-0
Predicate.java
...in/java/com/virjar/superappium/xpath/model/Predicate.java
+25
-0
XNodes.java
.../main/java/com/virjar/superappium/xpath/model/XNodes.java
+4
-0
XpathEvaluator.java
...va/com/virjar/superappium/xpath/model/XpathEvaluator.java
+25
-11
XpathNode.java
...in/java/com/virjar/superappium/xpath/model/XpathNode.java
+5
-1
TokenQueue.java
.../java/com/virjar/superappium/xpath/parser/TokenQueue.java
+3
-0
XpathStateMachine.java
...om/virjar/superappium/xpath/parser/XpathStateMachine.java
+8
-1
ExpressionParser.java
...superappium/xpath/parser/expression/ExpressionParser.java
+146
-0
OperatorEnv.java
...rjar/superappium/xpath/parser/expression/OperatorEnv.java
+121
-0
SyntaxNode.java
...irjar/superappium/xpath/parser/expression/SyntaxNode.java
+7
-0
AlgorithmUnit.java
...perappium/xpath/parser/expression/node/AlgorithmUnit.java
+16
-0
BooleanRevertUnit.java
...ppium/xpath/parser/expression/node/BooleanRevertUnit.java
+11
-0
FunctionNode.java
...uperappium/xpath/parser/expression/node/FunctionNode.java
+24
-0
WrapperUnit.java
...superappium/xpath/parser/expression/node/WrapperUnit.java
+18
-0
AddUnit.java
...superappium/xpath/parser/expression/operator/AddUnit.java
+57
-0
And2Unit.java
...uperappium/xpath/parser/expression/operator/And2Unit.java
+22
-0
AndUnit.java
...superappium/xpath/parser/expression/operator/AndUnit.java
+28
-0
ContainUnit.java
...rappium/xpath/parser/expression/operator/ContainUnit.java
+21
-0
DivideUnit.java
...erappium/xpath/parser/expression/operator/DivideUnit.java
+65
-0
EndWithUnit.java
...rappium/xpath/parser/expression/operator/EndWithUnit.java
+22
-0
EqualUnit.java
...perappium/xpath/parser/expression/operator/EqualUnit.java
+25
-0
GreaterEqualUnit.java
...um/xpath/parser/expression/operator/GreaterEqualUnit.java
+15
-0
GreaterThanUnit.java
...ium/xpath/parser/expression/operator/GreaterThanUnit.java
+32
-0
LessEqualUnit.java
...ppium/xpath/parser/expression/operator/LessEqualUnit.java
+15
-0
LessThanUnit.java
...appium/xpath/parser/expression/operator/LessThanUnit.java
+27
-0
MinusUnit.java
...perappium/xpath/parser/expression/operator/MinusUnit.java
+63
-0
MultiUnit.java
...perappium/xpath/parser/expression/operator/MultiUnit.java
+66
-0
NotEqualUnit.java
...appium/xpath/parser/expression/operator/NotEqualUnit.java
+15
-0
NotMatchUnit.java
...appium/xpath/parser/expression/operator/NotMatchUnit.java
+15
-0
OpKey.java
...r/superappium/xpath/parser/expression/operator/OpKey.java
+22
-0
Or2Unit.java
...superappium/xpath/parser/expression/operator/Or2Unit.java
+21
-0
OrUnit.java
.../superappium/xpath/parser/expression/operator/OrUnit.java
+26
-0
RegexUnit.java
...perappium/xpath/parser/expression/operator/RegexUnit.java
+23
-0
RemainderUnit.java
...ppium/xpath/parser/expression/operator/RemainderUnit.java
+65
-0
StartWithUnit.java
...ppium/xpath/parser/expression/operator/StartWithUnit.java
+22
-0
priority.txt
...superappium/xpath/parser/expression/operator/priority.txt
+22
-0
Token.java
...rjar/superappium/xpath/parser/expression/token/Token.java
+12
-0
TokenAnalysisRegistry.java
.../xpath/parser/expression/token/TokenAnalysisRegistry.java
+114
-0
TokenConsumer.java
...erappium/xpath/parser/expression/token/TokenConsumer.java
+11
-0
TokenHandler.java
...perappium/xpath/parser/expression/token/TokenHandler.java
+10
-0
AttributeActionConsumer.java
...er/expression/token/consumer/AttributeActionConsumer.java
+26
-0
BooleanConsumer.java
...ath/parser/expression/token/consumer/BooleanConsumer.java
+25
-0
DefaultWordConsumer.java
...parser/expression/token/consumer/DefaultWordConsumer.java
+25
-0
DefaultXpathConsumer.java
...arser/expression/token/consumer/DefaultXpathConsumer.java
+37
-0
DigitConsumer.java
...xpath/parser/expression/token/consumer/DigitConsumer.java
+26
-0
ExpressionConsumer.java
.../parser/expression/token/consumer/ExpressionConsumer.java
+27
-0
FunctionConsumer.java
...th/parser/expression/token/consumer/FunctionConsumer.java
+25
-0
OperatorConsumer.java
...th/parser/expression/token/consumer/OperatorConsumer.java
+32
-0
StringConstantConsumer.java
...ser/expression/token/consumer/StringConstantConsumer.java
+27
-0
XpathConsumer.java
...xpath/parser/expression/token/consumer/XpathConsumer.java
+27
-0
AttributeHandler.java
...ath/parser/expression/token/handler/AttributeHandler.java
+17
-0
BooleanHandler.java
...xpath/parser/expression/token/handler/BooleanHandler.java
+22
-0
ConstantHandler.java
...path/parser/expression/token/handler/ConstantHandler.java
+24
-0
ExpressionHandler.java
...th/parser/expression/token/handler/ExpressionHandler.java
+23
-0
FunctionHandler.java
...path/parser/expression/token/handler/FunctionHandler.java
+19
-0
NumberHandler.java
.../xpath/parser/expression/token/handler/NumberHandler.java
+29
-0
XpathHandler.java
...m/xpath/parser/expression/token/handler/XpathHandler.java
+29
-0
XpathUtil.java
...ain/java/com/virjar/superappium/xpath/util/XpathUtil.java
+59
-0
No files found.
super-appium/src/main/java/com/virjar/superappium/util/Lists.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
util
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.LinkedList
;
/**
* some utils migrated from guava
*/
public
class
Lists
{
public
static
<
E
>
ArrayList
<
E
>
newArrayList
(
E
...
elements
)
{
// Avoid integer overflow when a large array is passed in
int
capacity
=
computeArrayListCapacity
(
elements
.
length
);
ArrayList
<
E
>
list
=
new
ArrayList
<
E
>(
capacity
);
Collections
.
addAll
(
list
,
elements
);
return
list
;
}
static
int
computeArrayListCapacity
(
int
arraySize
)
{
return
saturatedCast
(
5L
+
arraySize
+
(
arraySize
/
10
));
}
/**
* Returns the {@code int} nearest in value to {@code value}.
*
* @param value any {@code long} value
* @return the same value cast to {@code int} if it is in the range of the
* {@code int} type, {@link Integer#MAX_VALUE} if it is too large,
* or {@link Integer#MIN_VALUE} if it is too small
*/
public
static
int
saturatedCast
(
long
value
)
{
if
(
value
>
Integer
.
MAX_VALUE
)
{
return
Integer
.
MAX_VALUE
;
}
if
(
value
<
Integer
.
MIN_VALUE
)
{
return
Integer
.
MIN_VALUE
;
}
return
(
int
)
value
;
}
public
static
<
E
>
LinkedList
<
E
>
newLinkedList
()
{
return
new
LinkedList
<
E
>();
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/XpathParser.java
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
;
import
com.virjar.superappium.xpath.exception.XpathSyntaxErrorException
;
import
com.virjar.superappium.xpath.model.XpathEvaluator
;
public
class
XpathParser
{
public
XpathParser
(
String
subXpath
)
{
}
public
static
void
compile
(
String
s
)
throws
XpathSyntaxErrorException
{
}
public
XpathEvaluator
parse
()
{
return
null
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/exception/EvaluateException.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
exception
;
public
class
EvaluateException
extends
RuntimeException
{
public
EvaluateException
()
{
}
public
EvaluateException
(
Throwable
cause
)
{
super
(
cause
);
}
public
EvaluateException
(
String
message
)
{
super
(
message
);
}
public
EvaluateException
(
String
message
,
Throwable
cause
)
{
super
(
message
,
cause
);
}
public
EvaluateException
(
String
message
,
Throwable
cause
,
boolean
enableSuppression
,
boolean
writableStackTrace
)
{
super
(
message
,
cause
,
enableSuppression
,
writableStackTrace
);
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/exception/NoSuchAxisException.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
exception
;
public
class
NoSuchAxisException
extends
XpathSyntaxErrorException
{
public
NoSuchAxisException
(
int
errorPos
,
String
msg
)
{
super
(
errorPos
,
msg
);
}
}
\ No newline at end of file
super-appium/src/main/java/com/virjar/superappium/xpath/function/FunctionEnv.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
function
;
import
android.util.Log
;
import
com.virjar.superappium.util.Constants
;
import
com.virjar.superappium.xpath.function.axis.AxisFunction
;
import
com.virjar.superappium.xpath.function.filter.FilterFunction
;
import
com.virjar.superappium.xpath.function.select.SelectFunction
;
import
java.util.HashMap
;
import
java.util.Map
;
public
class
FunctionEnv
{
private
static
Map
<
String
,
SelectFunction
>
selectFunctions
=
new
HashMap
<>();
private
static
Map
<
String
,
FilterFunction
>
filterFunctions
=
new
HashMap
<>();
private
static
Map
<
String
,
AxisFunction
>
axisFunctions
=
new
HashMap
<>();
static
{
registerAllSelectFunctions
();
registerAllFilterFunctions
();
registerAllAxisFunctions
();
}
public
static
SelectFunction
getSelectFunction
(
String
functionName
)
{
return
selectFunctions
.
get
(
functionName
);
}
public
static
FilterFunction
getFilterFunction
(
String
functionName
)
{
return
filterFunctions
.
get
(
functionName
);
}
public
static
AxisFunction
getAxisFunction
(
String
functionName
)
{
return
axisFunctions
.
get
(
functionName
);
}
public
synchronized
static
void
registerSelectFunction
(
SelectFunction
selectFunction
)
{
if
(
selectFunctions
.
containsKey
(
selectFunction
.
getName
()))
{
Log
.
w
(
Constants
.
TAG
,
"register a duplicate select function "
+
selectFunction
.
getName
());
}
selectFunctions
.
put
(
selectFunction
.
getName
(),
selectFunction
);
}
public
synchronized
static
void
registerFilterFunction
(
FilterFunction
filterFunction
)
{
if
(
filterFunctions
.
containsKey
(
filterFunction
.
getName
()))
{
Log
.
w
(
Constants
.
TAG
,
"register a duplicate filter function "
+
filterFunction
.
getName
());
}
filterFunctions
.
put
(
filterFunction
.
getName
(),
filterFunction
);
}
public
synchronized
static
void
registerAxisFunciton
(
AxisFunction
axisFunction
)
{
if
(
axisFunctions
.
containsKey
(
axisFunction
.
getName
()))
{
Log
.
w
(
Constants
.
TAG
,
"register a duplicate axis function "
+
axisFunction
.
getName
());
}
axisFunctions
.
put
(
axisFunction
.
getName
(),
axisFunction
);
}
private
static
void
registerAllSelectFunctions
()
{
}
private
static
void
registerAllFilterFunctions
()
{
}
private
static
void
registerAllAxisFunctions
()
{
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/function/NameAware.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
function
;
public
interface
NameAware
{
String
getName
();
}
super-appium/src/main/java/com/virjar/superappium/xpath/function/axis/AxisFunction.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
function
.
axis
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.function.NameAware
;
import
java.util.List
;
public
interface
AxisFunction
extends
NameAware
{
//TODO 是否允许轴函数存在参数
List
<
ViewImage
>
call
(
ViewImage
viewImage
,
List
<
String
>
args
);
}
super-appium/src/main/java/com/virjar/superappium/xpath/function/filter/FilterFunction.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
function
.
filter
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.function.NameAware
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
import
java.util.List
;
public
interface
FilterFunction
extends
NameAware
{
Object
call
(
ViewImage
viewImage
,
List
<
SyntaxNode
>
params
);
}
super-appium/src/main/java/com/virjar/superappium/xpath/function/select/SelectFunction.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
function
.
select
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.function.NameAware
;
import
com.virjar.superappium.xpath.model.XNode
;
import
com.virjar.superappium.xpath.model.XpathNode
;
import
java.util.List
;
public
interface
SelectFunction
extends
NameAware
{
List
<
XNode
>
call
(
XpathNode
.
ScopeEm
scopeEm
,
List
<
ViewImage
>
elements
,
List
<
String
>
args
);
}
super-appium/src/main/java/com/virjar/superappium/xpath/model/Predicate.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
model
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.util.Lists
;
import
com.virjar.superappium.xpath.function.FunctionEnv
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
import
lombok.Getter
;
public
class
Predicate
{
private
SyntaxNode
syntaxNode
;
@Getter
private
String
predicateStr
;
public
Predicate
(
String
predicateStr
,
SyntaxNode
syntaxNode
)
{
this
.
predicateStr
=
predicateStr
;
this
.
syntaxNode
=
syntaxNode
;
}
boolean
isValid
(
ViewImage
element
)
{
return
(
Boolean
)
FunctionEnv
.
getFilterFunction
(
"sipSoupPredictJudge"
).
call
(
element
,
Lists
.
newArrayList
(
syntaxNode
));
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/model/XNodes.java
View file @
c352e39c
...
...
@@ -8,4 +8,8 @@ public class XNodes extends LinkedList<XNode> {
public
XNodes
(
List
<
XNode
>
handleNode
)
{
super
(
handleNode
);
}
public
XNodes
(
XNode
e
)
{
add
(
e
);
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/model/XpathEvaluator.java
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
model
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.util.Lists
;
import
com.virjar.superappium.xpath.function.axis.AxisFunction
;
import
com.virjar.superappium.xpath.util.XpathUtil
;
import
java.util.Iterator
;
import
java.util.LinkedList
;
...
...
@@ -47,7 +50,7 @@ public abstract class XpathEvaluator {
if
(
axis
!=
null
)
{
contextElements
=
Lists
.
newLinkedList
();
for
(
ViewImage
element
:
elements
)
{
ViewImage
call
=
axis
.
call
(
element
,
xpathNode
.
getAxisParams
());
List
<
ViewImage
>
call
=
axis
.
call
(
element
,
xpathNode
.
getAxisParams
());
if
(
call
!=
null
)
{
contextElements
.
addAll
(
call
);
}
...
...
@@ -57,21 +60,32 @@ public abstract class XpathEvaluator {
}
// 调用抽取函数
List
<
XNode
>
SIPNodes
=
xpathNode
.
getSelectFunction
().
call
(
xpathNode
.
getScopeEm
(),
new
Elements
(
contextElements
)
,
xpathNode
.
getSelectParams
());
List
<
XNode
>
xNodesList
=
xpathNode
.
getSelectFunction
().
call
(
xpathNode
.
getScopeEm
(),
contextElements
,
xpathNode
.
getSelectParams
());
// 谓语过滤
if
(
xpathNode
.
getPredicate
()
==
null
)
{
return
SIPNodes
;
if
(
xpathNode
.
getPredicate
s
()
==
null
)
{
return
xNodesList
;
}
// 谓语只支持对元素过滤,非元素节点直接被过滤
return
Lists
.
newLinkedList
(
Iterables
.
filter
(
SIPNodes
,
new
Predicate
<
XNode
>()
{
@Override
public
boolean
apply
(
XNode
input
)
{
return
xpathNode
.
getPredicate
().
isValid
(
input
.
getElement
())
;
List
<
XNode
>
finalResult
=
Lists
.
newLinkedList
();
//两层循环
for
(
XNode
xNode
:
xNodesList
)
{
if
(
xNode
.
isText
()
)
{
continue
;
}
}));
boolean
valid
=
true
;
for
(
Predicate
predicate
:
xpathNode
.
getPredicates
())
{
if
(!
predicate
.
isValid
(
xNode
.
getElement
()))
{
valid
=
false
;
break
;
}
}
if
(
valid
)
{
finalResult
.
add
(
xNode
);
}
}
return
finalResult
;
}
@Override
...
...
super-appium/src/main/java/com/virjar/superappium/xpath/model/XpathNode.java
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
model
;
import
com.virjar.superappium.xpath.function.axis.AxisFunction
;
import
com.virjar.superappium.xpath.function.select.SelectFunction
;
import
java.util.LinkedList
;
import
java.util.List
;
import
lombok.Getter
;
...
...
@@ -44,7 +48,7 @@ public class XpathNode {
*/
@Getter
@Setter
private
Predicate
predicate
;
private
LinkedList
<
Predicate
>
predicates
=
new
LinkedList
<>()
;
@Setter
@Getter
...
...
super-appium/src/main/java/com/virjar/superappium/xpath/parser/TokenQueue.java
View file @
c352e39c
...
...
@@ -2,7 +2,10 @@ package com.virjar.superappium.xpath.parser;
import
com.virjar.superappium.util.StringUtils
;
import
lombok.Getter
;
public
class
TokenQueue
{
@Getter
protected
String
queue
;
protected
int
pos
=
0
;
...
...
super-appium/src/main/java/com/virjar/superappium/xpath/parser/XpathStateMachine.java
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
;
import
com.virjar.superappium.util.Lists
;
import
com.virjar.superappium.util.StringUtils
;
import
com.virjar.superappium.xpath.XpathParser
;
import
com.virjar.superappium.xpath.exception.NoSuchAxisException
;
import
com.virjar.superappium.xpath.exception.XpathSyntaxErrorException
;
import
com.virjar.superappium.xpath.function.FunctionEnv
;
import
com.virjar.superappium.xpath.function.axis.AxisFunction
;
import
com.virjar.superappium.xpath.model.Predicate
;
import
com.virjar.superappium.xpath.model.XpathEvaluator
;
import
com.virjar.superappium.xpath.model.XpathNode
;
import
com.virjar.superappium.xpath.parser.expression.ExpressionParser
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
...
...
@@ -294,7 +301,7 @@ public class XpathStateMachine {
String
predicate
=
stateMachine
.
tokenQueue
.
chompBalanced
(
'['
,
']'
);
SyntaxNode
predicateTree
=
new
ExpressionParser
(
new
TokenQueue
(
predicate
)).
parse
();
stateMachine
.
xpathChain
.
getLast
()
.
setPredicate
(
new
Predicate
(
StringUtils
.
trimToEmpty
(
predicate
),
predicateTree
));
.
getPredicates
().
add
(
new
Predicate
(
StringUtils
.
trimToEmpty
(
predicate
),
predicateTree
));
}
// check
stateMachine
.
tokenQueue
.
consumeWhitespace
();
...
...
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/ExpressionParser.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
;
import
com.virjar.superappium.util.Lists
;
import
com.virjar.superappium.xpath.exception.XpathSyntaxErrorException
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenAnalysisRegistry
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenConsumer
;
import
java.util.EmptyStackException
;
import
java.util.List
;
import
java.util.Stack
;
import
lombok.Getter
;
public
class
ExpressionParser
{
private
TokenQueue
expressionTokenQueue
;
public
ExpressionParser
(
TokenQueue
expressionTokenQueue
)
{
this
.
expressionTokenQueue
=
expressionTokenQueue
;
}
private
SyntaxNode
innerParse
()
throws
XpathSyntaxErrorException
{
// 表达式拆分成token流
List
<
TokenHolder
>
tokenStream
=
tokenStream
();
// 构建逆波兰式
Stack
<
TokenHolder
>
stack
=
new
Stack
<>();
// RPN就是逆波兰式的含义
List
<
TokenHolder
>
RPN
=
Lists
.
newLinkedList
();
TokenHolder
bottom
=
new
TokenHolder
(
"#"
,
null
);
stack
.
push
(
bottom
);
for
(
TokenHolder
tokenHolder
:
tokenStream
)
{
if
(
tokenHolder
.
type
.
equals
(
Token
.
OPERATOR
))
{
TokenHolder
preSymbol
=
stack
.
peek
();
while
(
compareSymbolPripority
(
tokenHolder
,
preSymbol
)
<=
0
)
{
RPN
.
add
(
preSymbol
);
stack
.
pop
();
preSymbol
=
stack
.
peek
();
}
stack
.
push
(
tokenHolder
);
}
else
{
RPN
.
add
(
tokenHolder
);
}
}
while
(!
stack
.
peek
().
expression
.
equals
(
"#"
))
{
RPN
.
add
(
stack
.
pop
());
}
// 构建计算树
Stack
<
SyntaxNode
>
computeStack
=
new
Stack
<>();
for
(
TokenHolder
tokenHolder
:
RPN
)
{
if
(
tokenHolder
.
type
.
equals
(
Token
.
OPERATOR
))
{
SyntaxNode
right
=
computeStack
.
pop
();
SyntaxNode
left
=
computeStack
.
pop
();
computeStack
.
push
(
buildAlgorithmUnit
(
tokenHolder
,
left
,
right
));
}
else
{
computeStack
.
push
(
buildByTokenHolder
(
tokenHolder
));
}
}
return
computeStack
.
pop
();
}
public
SyntaxNode
parse
()
throws
XpathSyntaxErrorException
{
try
{
return
innerParse
();
}
catch
(
EmptyStackException
e
)
{
throw
new
XpathSyntaxErrorException
(
0
,
"不能识别表达式:"
+
expressionTokenQueue
.
getQueue
(),
e
);
}
}
private
SyntaxNode
buildAlgorithmUnit
(
TokenHolder
tokenHolder
,
SyntaxNode
left
,
SyntaxNode
right
)
{
// 对于计算树,属于内部节点,需要附加左右操作树,不能单纯根据token信息产生节点
// Preconditions.checkArgument(tokenHolder.type.equals(Token.OPERATOR));
AlgorithmUnit
algorithmUnit
=
OperatorEnv
.
createByName
(
tokenHolder
.
expression
);
algorithmUnit
.
setLeft
(
left
);
algorithmUnit
.
setRight
(
right
);
return
algorithmUnit
;
}
/**
* 非操作符的节点构建,如函数,xpath表达式,常量,数字等,他们的构造方法和计算树无关,是表达式里面最原始的计算叶节点
*
* @param tokenHolder token数据
* @return 用来挂在计算树上面的叶节点
*/
private
SyntaxNode
buildByTokenHolder
(
TokenHolder
tokenHolder
)
throws
XpathSyntaxErrorException
{
//Preconditions.checkArgument(!tokenHolder.type.equals(Token.OPERATOR));
// return TokenNodeFactory.hintAndGen(tokenHolder);
return
TokenAnalysisRegistry
.
findHandler
(
tokenHolder
.
getType
()).
parseToken
(
tokenHolder
.
expression
);
}
private
int
compareSymbolPripority
(
TokenHolder
first
,
TokenHolder
second
)
{
// 不能直接减,否则可能溢出
return
Integer
.
valueOf
(
OperatorEnv
.
judgePriority
(
first
.
expression
))
.
compareTo
(
OperatorEnv
.
judgePriority
(
second
.
expression
));
}
private
List
<
TokenHolder
>
tokenStream
()
throws
XpathSyntaxErrorException
{
List
<
TokenHolder
>
tokenStream
=
Lists
.
newLinkedList
();
// java不支持逗号表达式,这么做达到了逗号表达式的效果
while
((
expressionTokenQueue
.
consumeWhitespace
()
||
!
expressionTokenQueue
.
consumeWhitespace
())
&&
!
expressionTokenQueue
.
isEmpty
())
{
boolean
hint
=
false
;
for
(
TokenConsumer
tokenConsumer
:
TokenAnalysisRegistry
.
consumerIterable
())
{
String
consume
=
tokenConsumer
.
consume
(
expressionTokenQueue
);
if
(
consume
==
null
)
{
continue
;
}
hint
=
true
;
tokenStream
.
add
(
new
TokenHolder
(
consume
,
tokenConsumer
.
tokenType
()));
break
;
}
if
(!
hint
)
{
// 不成功,报错
throw
new
XpathSyntaxErrorException
(
expressionTokenQueue
.
nowPosition
(),
"can not parse predicate"
+
expressionTokenQueue
.
getQueue
()
+
" for token "
+
expressionTokenQueue
.
remainder
());
}
}
return
tokenStream
;
}
public
static
class
TokenHolder
{
public
TokenHolder
(
String
expression
,
String
type
)
{
this
.
expression
=
expression
;
this
.
type
=
type
;
}
@Getter
private
String
type
;
@Getter
private
String
expression
;
@Override
public
String
toString
()
{
return
expression
;
}
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/OperatorEnv.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
;
import
com.virjar.superappium.util.Lists
;
import
com.virjar.superappium.util.StringUtils
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.parser.expression.operator.OpKey
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.TreeSet
;
import
lombok.Getter
;
public
class
OperatorEnv
{
private
static
TreeSet
<
AlgorithmHolder
>
allOperators
=
new
TreeSet
<>();
private
static
HashMap
<
String
,
AlgorithmHolder
>
operatorMaps
=
new
HashMap
<>();
static
{
registerDefault
();
}
@SuppressWarnings
(
"unchecked"
)
private
static
void
registerDefault
()
{
ClassScanner
.
AnnotationClassVisitor
visitor
=
new
ClassScanner
.
AnnotationClassVisitor
(
OpKey
.
class
);
ClassScanner
.
scan
(
visitor
,
Lists
.
newArrayList
(
"com.virjar.sipsoup.parse.expression.operator"
));
Set
<
Class
>
classSet
=
visitor
.
getClassSet
();
for
(
Class
clazz
:
classSet
)
{
if
(
AlgorithmUnit
.
class
.
isAssignableFrom
(
clazz
))
{
addOperator
(
clazz
);
}
}
}
public
static
void
addOperator
(
String
key
,
int
priority
,
Class
<?
extends
AlgorithmUnit
>
algorithmUnit
)
{
if
(
"#"
.
equals
(
key
))
{
throw
new
IllegalStateException
(
"\"#\" can not to be register a operator,please contact author virjar@virjar.com"
))
;
}
AlgorithmHolder
holder
=
new
AlgorithmHolder
(
algorithmUnit
,
key
,
priority
);
allOperators
.
add
(
holder
);
operatorMaps
.
put
(
key
,
holder
);
}
public
static
void
addOperator
(
Class
<?
extends
AlgorithmUnit
>
algorithmUnitClass
)
{
OpKey
annotation
=
algorithmUnitClass
.
getAnnotation
(
OpKey
.
class
);
if
(
annotation
==
null
)
{
throw
new
IllegalStateException
(
"can not register operator for class "
+
algorithmUnitClass
+
",such can not resolve operator name"
);
}
String
key
=
annotation
.
value
();
if
(
StringUtils
.
isBlank
(
key
))
{
throw
new
IllegalStateException
(
"can not register operator for class "
+
algorithmUnitClass
+
" ,such operator name is empty"
);
}
addOperator
(
key
,
annotation
.
priority
(),
algorithmUnitClass
);
}
public
static
AlgorithmUnit
createByName
(
String
operatorName
)
{
AlgorithmHolder
holder
=
operatorMaps
.
get
(
operatorName
);
return
ObjectFactory
.
newInstance
(
holder
.
aClass
);
}
public
static
int
judgePriority
(
String
operatorName
)
{
if
(
"#"
.
equals
(
operatorName
))
{
// 这是一个特殊逻辑,运算栈需要有一个兜底判断的操作符,所以#是RPN默认的一个运算符,但是他不会表现在编译好的语法树里面
return
Integer
.
MIN_VALUE
;
}
AlgorithmHolder
holder
=
operatorMaps
.
get
(
operatorName
);
return
holder
.
priority
;
}
public
static
synchronized
List
<
AlgorithmHolder
>
allAlgorithmUnitList
()
{
return
Lists
.
newCopyOnWriteArrayList
(
allOperators
);
}
public
static
class
AlgorithmHolder
implements
Comparable
<
AlgorithmHolder
>
{
@Getter
private
String
key
;
@Getter
private
Class
<?
extends
AlgorithmUnit
>
aClass
;
private
int
priority
;
public
AlgorithmHolder
(
Class
<?
extends
AlgorithmUnit
>
aClass
,
String
key
,
int
priority
)
{
this
.
aClass
=
aClass
;
this
.
key
=
key
;
this
.
priority
=
priority
;
}
@Override
public
int
compareTo
(
AlgorithmHolder
o
)
{
String
thisKey
=
key
;
String
otherKey
=
o
.
key
;
if
(
thisKey
.
length
()
!=
otherKey
.
length
())
{
return
otherKey
.
length
()
-
thisKey
.
length
();
}
return
thisKey
.
compareTo
(
otherKey
);
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
AlgorithmHolder
that
=
(
AlgorithmHolder
)
o
;
return
key
!=
null
?
key
.
equals
(
that
.
key
)
:
that
.
key
==
null
;
}
@Override
public
int
hashCode
()
{
return
key
!=
null
?
key
.
hashCode
()
:
0
;
}
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/SyntaxNode.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
;
import
com.virjar.superappium.ViewImage
;
public
interface
SyntaxNode
{
Object
calc
(
ViewImage
viewImage
);
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/node/AlgorithmUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
node
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
public
abstract
class
AlgorithmUnit
implements
SyntaxNode
{
protected
SyntaxNode
left
=
null
;
protected
SyntaxNode
right
=
null
;
public
void
setLeft
(
SyntaxNode
left
)
{
this
.
left
=
left
;
}
public
void
setRight
(
SyntaxNode
right
)
{
this
.
right
=
right
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/node/BooleanRevertUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
node
;
import
com.virjar.superappium.ViewImage
;
public
abstract
class
BooleanRevertUnit
extends
WrapperUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
return
!((
Boolean
)
wrap
().
calc
(
element
));
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/node/FunctionNode.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
node
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.function.filter.FilterFunction
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
import
java.util.List
;
public
class
FunctionNode
implements
SyntaxNode
{
private
FilterFunction
filterFunction
;
private
List
<
SyntaxNode
>
filterFunctionParams
;
public
FunctionNode
(
FilterFunction
filterFunction
,
List
<
SyntaxNode
>
filterFunctionParams
)
{
this
.
filterFunction
=
filterFunction
;
this
.
filterFunctionParams
=
filterFunctionParams
;
}
@Override
public
Object
calc
(
ViewImage
viewImage
)
{
return
filterFunction
.
call
(
viewImage
,
filterFunctionParams
);
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/node/WrapperUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
node
;
import
com.virjar.superappium.xpath.parser.expression.OperatorEnv
;
public
abstract
class
WrapperUnit
extends
AlgorithmUnit
{
private
AlgorithmUnit
delegate
=
null
;
protected
abstract
String
targetName
();
protected
AlgorithmUnit
wrap
()
{
if
(
delegate
==
null
)
{
delegate
=
OperatorEnv
.
createByName
(
targetName
());
delegate
.
setLeft
(
left
);
delegate
.
setRight
(
right
);
}
return
delegate
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/AddUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.util.XpathUtil
;
import
java.math.BigDecimal
;
/**
* Created by virjar on 17/6/10.
*
* @author virjar
* @since 0.0.1 加法运算
*/
@OpKey
(
value
=
"+"
,
priority
=
20
)
public
class
AddUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
||
rightValue
==
null
)
{
return
XpathUtil
.
toPlainString
(
leftValue
)
+
XpathUtil
.
toPlainString
(
rightValue
);
}
// 左右都不为空,开始计算
// step one think as number
if
(
leftValue
instanceof
Number
&&
rightValue
instanceof
Number
)
{
// 都是整数,则执行整数加法
if
(
leftValue
instanceof
Integer
&&
rightValue
instanceof
Integer
)
{
return
(
Integer
)
leftValue
+
(
Integer
)
rightValue
;
}
// 包含小数,转double执行加法
if
(
leftValue
instanceof
Double
||
rightValue
instanceof
Double
||
leftValue
instanceof
Float
||
rightValue
instanceof
Float
)
{
return
((
Number
)
leftValue
).
doubleValue
()
+
((
Number
)
rightValue
).
doubleValue
();
}
// 包含BigDecimal 转bigDecimal
if
(
leftValue
instanceof
BigDecimal
||
rightValue
instanceof
BigDecimal
)
{
return
XpathUtil
.
toBigDecimal
((
Number
)
leftValue
).
add
(
XpathUtil
.
toBigDecimal
((
Number
)
rightValue
));
}
// 包含长整数,且不包含小数,全部转化为长整数计算
if
(
leftValue
instanceof
Long
||
rightValue
instanceof
Long
)
{
return
((
Number
)
leftValue
).
longValue
()
+
((
Number
)
rightValue
).
longValue
();
}
// 兜底,用double执行计算
return
((
Number
)
leftValue
).
doubleValue
()
+
((
Number
)
rightValue
).
doubleValue
();
}
// 有一方不是数字,转化为字符串进行链接
return
XpathUtil
.
toPlainString
(
leftValue
)
+
XpathUtil
.
toPlainString
(
rightValue
);
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/And2Unit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.node.WrapperUnit
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"and"
,
priority
=
0
)
public
class
And2Unit
extends
WrapperUnit
{
@Override
protected
String
targetName
()
{
return
"&&"
;
}
@Override
public
Object
calc
(
ViewImage
element
)
{
return
wrap
().
calc
(
element
);
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/AndUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"&&"
,
priority
=
0
)
public
class
AndUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
||
rightValue
==
null
)
{
return
Boolean
.
FALSE
;
}
// 左右都不为空,开始计算
// step one think as number
if
(
leftValue
instanceof
Boolean
&&
rightValue
instanceof
Boolean
)
{
return
(
Boolean
)
leftValue
&&
(
Boolean
)
rightValue
;
}
return
Boolean
.
FALSE
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/ContainUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.util.XpathUtil
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"*="
,
priority
=
10
)
public
class
ContainUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
||
rightValue
==
null
)
{
return
Boolean
.
FALSE
;
}
return
XpathUtil
.
toPlainString
(
leftValue
).
contains
(
XpathUtil
.
toPlainString
(
rightValue
));
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/DivideUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.exception.EvaluateException
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.util.XpathUtil
;
import
java.math.BigDecimal
;
/**
* Created by virjar on 17/6/10.
*
* @author virjar
* @since 0.0.1 除法运算
*/
@OpKey
(
value
=
"/"
,
priority
=
30
)
public
class
DivideUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
||
rightValue
==
null
)
{
throw
new
EvaluateException
(
"operate is null,left: "
+
leftValue
+
" right:"
+
rightValue
);
}
// 左右都不为空,开始计算
// step one think as number
if
(
leftValue
instanceof
Number
&&
rightValue
instanceof
Number
)
{
// 都是整数,则执行整数除法
if
(
leftValue
instanceof
Integer
&&
rightValue
instanceof
Integer
)
{
return
(
Integer
)
leftValue
/
(
Integer
)
rightValue
;
}
// 包含小数,转double执行除法
if
(
leftValue
instanceof
Double
||
rightValue
instanceof
Double
||
leftValue
instanceof
Float
||
rightValue
instanceof
Float
)
{
return
((
Number
)
leftValue
).
doubleValue
()
/
((
Number
)
rightValue
).
doubleValue
();
}
// 包含BigDecimal 转bigDecimal
if
(
leftValue
instanceof
BigDecimal
||
rightValue
instanceof
BigDecimal
)
{
if
(
leftValue
instanceof
BigDecimal
&&
rightValue
instanceof
BigDecimal
)
{
return
((
BigDecimal
)
leftValue
).
divide
((
BigDecimal
)
rightValue
,
BigDecimal
.
ROUND_HALF_UP
);
// 默认四舍五入
}
BigDecimal
newLeft
=
XpathUtil
.
toBigDecimal
((
Number
)
leftValue
);
BigDecimal
newRight
=
XpathUtil
.
toBigDecimal
((
Number
)
rightValue
);
return
newLeft
.
divide
(
newRight
,
BigDecimal
.
ROUND_HALF_UP
);
}
// 包含长整数,且不包含小数,全部转化为长整数计算
if
(
leftValue
instanceof
Long
||
rightValue
instanceof
Long
)
{
return
((
Number
)
leftValue
).
longValue
()
/
((
Number
)
rightValue
).
longValue
();
}
// 兜底,用double执行计算
return
((
Number
)
leftValue
).
doubleValue
()
/
((
Number
)
rightValue
).
doubleValue
();
}
throw
new
EvaluateException
(
"divide operate must with number parameter left:"
+
leftValue
+
" right:"
+
rightValue
);
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/EndWithUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.util.XpathUtil
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"$="
,
priority
=
10
)
public
class
EndWithUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
||
rightValue
==
null
)
{
return
Boolean
.
FALSE
;
}
return
XpathUtil
.
toPlainString
(
leftValue
).
endsWith
(
XpathUtil
.
toPlainString
(
rightValue
));
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/EqualUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"="
,
priority
=
10
)
public
class
EqualUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
&&
rightValue
==
null
)
{
return
Boolean
.
TRUE
;
}
if
(
leftValue
==
null
||
rightValue
==
null
)
{
return
Boolean
.
FALSE
;
}
return
leftValue
.
equals
(
rightValue
);
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/GreaterEqualUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.xpath.parser.expression.node.BooleanRevertUnit
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
">="
,
priority
=
10
)
public
class
GreaterEqualUnit
extends
BooleanRevertUnit
{
@Override
protected
String
targetName
()
{
return
"<"
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/GreaterThanUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.util.XpathUtil
;
/**
* Created by virjar on 17/6/10.
*
* @author virjar
* @since 0.0.1 大于> 运算
*/
@OpKey
(
value
=
">"
,
priority
=
10
)
public
class
GreaterThanUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
||
rightValue
==
null
)
{
return
XpathUtil
.
toPlainString
(
leftValue
).
compareTo
(
XpathUtil
.
toPlainString
(
rightValue
))
>
0
;
}
// 左右都不为空,开始计算
// step one think as number
if
(
leftValue
instanceof
Number
&&
rightValue
instanceof
Number
)
{
return
((
Number
)
leftValue
).
doubleValue
()
>
((
Number
)
rightValue
).
doubleValue
();
}
return
XpathUtil
.
toPlainString
(
leftValue
).
compareTo
(
XpathUtil
.
toPlainString
(
rightValue
))
>
0
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/LessEqualUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.xpath.parser.expression.node.BooleanRevertUnit
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"<="
,
priority
=
10
)
public
class
LessEqualUnit
extends
BooleanRevertUnit
{
@Override
protected
String
targetName
()
{
return
">"
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/LessThanUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.util.XpathUtil
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"<"
,
priority
=
10
)
public
class
LessThanUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
||
rightValue
==
null
)
{
return
XpathUtil
.
toPlainString
(
rightValue
).
compareTo
(
XpathUtil
.
toPlainString
(
rightValue
))
<
0
;
}
// 左右都不为空,开始计算
// step one think as number
if
(
leftValue
instanceof
Number
&&
rightValue
instanceof
Number
)
{
return
((
Number
)
leftValue
).
doubleValue
()
<
((
Number
)
rightValue
).
doubleValue
();
}
return
XpathUtil
.
toPlainString
(
leftValue
).
compareTo
(
XpathUtil
.
toPlainString
(
rightValue
))
<
0
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/MinusUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.exception.EvaluateException
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.util.XpathUtil
;
import
java.math.BigDecimal
;
/**
* Created by virjar on 17/6/10.
*
* @author virjar
* @since 0.0.1 减法运算
*/
@OpKey
(
value
=
"-"
,
priority
=
20
)
public
class
MinusUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
||
rightValue
==
null
)
{
throw
new
EvaluateException
(
"operate is null,left: "
+
leftValue
+
" right:"
+
rightValue
);
}
// 左右都不为空,开始计算
// step one think as number
if
(
leftValue
instanceof
Number
&&
rightValue
instanceof
Number
)
{
// 都是整数,则执行整数除法
if
(
leftValue
instanceof
Integer
&&
rightValue
instanceof
Integer
)
{
return
(
Integer
)
leftValue
-
(
Integer
)
rightValue
;
}
// 包含小数,转double执行除法
if
(
leftValue
instanceof
Double
||
rightValue
instanceof
Double
||
leftValue
instanceof
Float
||
rightValue
instanceof
Float
)
{
return
((
Number
)
leftValue
).
doubleValue
()
-
((
Number
)
rightValue
).
doubleValue
();
}
// 包含BigDecimal 转bigDecimal
if
(
leftValue
instanceof
BigDecimal
||
rightValue
instanceof
BigDecimal
)
{
if
(
leftValue
instanceof
BigDecimal
&&
rightValue
instanceof
BigDecimal
)
{
return
((
BigDecimal
)
leftValue
).
subtract
((
BigDecimal
)
rightValue
);
}
BigDecimal
newLeft
=
XpathUtil
.
toBigDecimal
((
Number
)
leftValue
);
BigDecimal
newRight
=
XpathUtil
.
toBigDecimal
((
Number
)
rightValue
);
return
newLeft
.
subtract
(
newRight
);
}
// 包含长整数,且不包含小数,全部转化为长整数计算
if
(
leftValue
instanceof
Long
||
rightValue
instanceof
Long
)
{
return
((
Number
)
leftValue
).
longValue
()
-
((
Number
)
rightValue
).
longValue
();
}
// 兜底,用double执行计算
return
((
Number
)
leftValue
).
doubleValue
()
-
((
Number
)
rightValue
).
doubleValue
();
}
throw
new
EvaluateException
(
"minus operate must with number parameter left:"
+
leftValue
+
" right:"
+
rightValue
);
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/MultiUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.exception.EvaluateException
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.util.XpathUtil
;
import
java.math.BigDecimal
;
/**
* Created by virjar on 17/6/10.
*
* @author virjar
* @since 0.0.1 乘法运算
*/
@OpKey
(
value
=
"*"
,
priority
=
30
)
public
class
MultiUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
||
rightValue
==
null
)
{
throw
new
EvaluateException
(
"operate is null,left: "
+
leftValue
+
" right:"
+
rightValue
);
}
// 左右都不为空,开始计算
// step one think as number
if
(
leftValue
instanceof
Number
&&
rightValue
instanceof
Number
)
{
// 都是整数,则执行整数除法
if
(
leftValue
instanceof
Integer
&&
rightValue
instanceof
Integer
)
{
return
(
Integer
)
leftValue
*
(
Integer
)
rightValue
;
}
// 包含小数,转double执行除法
if
(
leftValue
instanceof
Double
||
rightValue
instanceof
Double
||
leftValue
instanceof
Float
||
rightValue
instanceof
Float
)
{
return
((
Number
)
leftValue
).
doubleValue
()
*
((
Number
)
rightValue
).
doubleValue
();
}
// 包含BigDecimal 转bigDecimal
if
(
leftValue
instanceof
BigDecimal
||
rightValue
instanceof
BigDecimal
)
{
if
(
leftValue
instanceof
BigDecimal
&&
rightValue
instanceof
BigDecimal
)
{
return
((
BigDecimal
)
leftValue
).
multiply
((
BigDecimal
)
rightValue
);
}
BigDecimal
newLeft
=
XpathUtil
.
toBigDecimal
((
Number
)
leftValue
);
BigDecimal
newRight
=
XpathUtil
.
toBigDecimal
((
Number
)
rightValue
);
return
newLeft
.
multiply
(
newRight
);
}
// 包含长整数,且不包含小数,全部转化为长整数计算
if
(
leftValue
instanceof
Long
||
rightValue
instanceof
Long
)
{
return
((
Number
)
leftValue
).
longValue
()
*
((
Number
)
rightValue
).
longValue
();
}
// 兜底,用double执行计算
return
((
Number
)
leftValue
).
doubleValue
()
*
((
Number
)
rightValue
).
doubleValue
();
}
throw
new
EvaluateException
(
"multiply operate must with number parameter left:"
+
leftValue
+
" right:"
+
rightValue
);
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/NotEqualUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.xpath.parser.expression.node.BooleanRevertUnit
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"!="
,
priority
=
10
)
public
class
NotEqualUnit
extends
BooleanRevertUnit
{
@Override
protected
String
targetName
()
{
return
"="
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/NotMatchUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.xpath.parser.expression.node.BooleanRevertUnit
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"!~"
,
priority
=
10
)
public
class
NotMatchUnit
extends
BooleanRevertUnit
{
@Override
protected
String
targetName
()
{
return
"~="
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/OpKey.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Created by virjar on 17/6/10.
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
public
@interface
OpKey
{
/**
* 操作符标志,xpath解析器会根据当前的字符是否是这个标记,决定使用对应的处理器进行运算
*
* @return 对应符号标记,如"+","-","*","/","%",">","<",">=",">=","!="
*/
String
value
();
int
priority
();
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/Or2Unit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.node.WrapperUnit
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"or"
,
priority
=
0
)
public
class
Or2Unit
extends
WrapperUnit
{
@Override
protected
String
targetName
()
{
return
"||"
;
}
@Override
public
Object
calc
(
ViewImage
element
)
{
return
wrap
().
calc
(
element
);
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/OrUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"||"
,
priority
=
0
)
public
class
OrUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
// 左边为true,右边不管是啥,都为真
if
(
leftValue
!=
null
&&
leftValue
instanceof
Boolean
&&
(
Boolean
)
leftValue
)
{
return
true
;
}
// 左边不为真,以右边为主
if
(
rightValue
!=
null
&&
rightValue
instanceof
Boolean
&&
(
Boolean
)
rightValue
)
{
return
true
;
}
return
Boolean
.
FALSE
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/RegexUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.util.XpathUtil
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"~="
,
priority
=
10
)
public
class
RegexUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
||
rightValue
==
null
)
{
return
Boolean
.
FALSE
;
}
return
XpathUtil
.
toPlainString
(
leftValue
).
matches
(
XpathUtil
.
toPlainString
(
rightValue
));
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/RemainderUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.exception.EvaluateException
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.util.XpathUtil
;
import
java.math.BigDecimal
;
/**
* Created by virjar on 17/6/10.
*
* @author virjar
* @since 0.0.1 模数运算
*/
@OpKey
(
value
=
"%"
,
priority
=
30
)
public
class
RemainderUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
||
rightValue
==
null
)
{
throw
new
EvaluateException
(
"operate is null,left: "
+
leftValue
+
" right:"
+
rightValue
);
}
// 左右都不为空,开始计算
// step one think as number
if
(
leftValue
instanceof
Number
&&
rightValue
instanceof
Number
)
{
// 都是整数,则执行整数除法
if
(
leftValue
instanceof
Integer
&&
rightValue
instanceof
Integer
)
{
return
(
Integer
)
leftValue
%
(
Integer
)
rightValue
;
}
// 包含小数,转double执行除法
if
(
leftValue
instanceof
Double
||
rightValue
instanceof
Double
||
leftValue
instanceof
Float
||
rightValue
instanceof
Float
)
{
return
((
Number
)
leftValue
).
doubleValue
()
%
((
Number
)
rightValue
).
doubleValue
();
}
// 包含BigDecimal 转bigDecimal
if
(
leftValue
instanceof
BigDecimal
||
rightValue
instanceof
BigDecimal
)
{
if
(
leftValue
instanceof
BigDecimal
&&
rightValue
instanceof
BigDecimal
)
{
return
((
BigDecimal
)
leftValue
).
remainder
((
BigDecimal
)
rightValue
);
}
BigDecimal
newLeft
=
XpathUtil
.
toBigDecimal
((
Number
)
leftValue
);
BigDecimal
newRight
=
XpathUtil
.
toBigDecimal
((
Number
)
rightValue
);
return
newLeft
.
remainder
(
newRight
);
}
// 包含长整数,且不包含小数,全部转化为长整数计算
if
(
leftValue
instanceof
Long
||
rightValue
instanceof
Long
)
{
return
((
Number
)
leftValue
).
longValue
()
%
((
Number
)
rightValue
).
longValue
();
}
// 兜底,用double执行计算
return
((
Number
)
leftValue
).
doubleValue
()
%
((
Number
)
rightValue
).
doubleValue
();
}
throw
new
EvaluateException
(
"remainder operate must with number parameter left:"
+
leftValue
+
" right:"
+
rightValue
);
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/StartWithUnit.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
operator
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.node.AlgorithmUnit
;
import
com.virjar.superappium.xpath.util.XpathUtil
;
/**
* Created by virjar on 17/6/10.
*/
@OpKey
(
value
=
"^="
,
priority
=
10
)
public
class
StartWithUnit
extends
AlgorithmUnit
{
@Override
public
Object
calc
(
ViewImage
element
)
{
Object
leftValue
=
left
.
calc
(
element
);
Object
rightValue
=
right
.
calc
(
element
);
if
(
leftValue
==
null
||
rightValue
==
null
)
{
return
Boolean
.
FALSE
;
}
return
XpathUtil
.
toPlainString
(
leftValue
).
startsWith
(
XpathUtil
.
toPlainString
(
rightValue
));
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/operator/priority.txt
0 → 100644
View file @
c352e39c
各运算符优先级定义
+ :20 加法运算
- :20 减法运算
* :30 乘法运算
/ :30 除法运算
% :30 取模运算
&& :0 逻辑且运算
|| :0 逻辑或运算
and :0 逻辑且运算,等价于&&
or :0 逻辑或运算,等价于||
= :10 相等判断,逻辑运算
> :10 大于,逻辑运算
< :10 小于,逻辑运算
>= :10 大于等于,逻辑运算
<= :10 小于等于,逻辑运算
*= :10 包含,测试表达式左侧数据是否包含表达式右侧数据,仅适用于字符串,逻辑运算
$= :10 以xxx结尾,测试左侧数据是否以表达式右侧数据结尾,仅适用于字符串,逻辑运算
^= :10 以xxx开始,测试左侧数据是否以表达式右侧数据开始,仅适用于字符串,逻辑运算
!= :10 不等于,和"="作用相反,逻辑运算
~= :10 模式匹配,测试左侧数据是否符合右侧字符串代表的正则表达式模式,仅适用于字符串,逻辑运算
!~ :10 不匹配,与"~="相反,如果左侧数据不匹配右侧字符串代表的正则表达式,则返回true
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/Token.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
;
public
class
Token
{
public
static
final
String
OPERATOR
=
"OPERATOR"
;
public
static
final
String
CONSTANT
=
"CONSTANT"
;
public
static
final
String
NUMBER
=
"NUMBER"
;
public
static
final
String
EXPRESSION
=
"EXPRESSION"
;
public
static
final
String
ATTRIBUTE_ACTION
=
"ATTRIBUTE_ACTION"
;
public
static
final
String
XPATH
=
"XPATH"
;
public
static
final
String
FUNCTION
=
"FUNCTION"
;
public
static
final
String
BOOLEAN
=
"BOOLEAN"
;
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/TokenAnalysisRegistry.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.token.consumer.AttributeActionConsumer
;
import
com.virjar.superappium.xpath.parser.expression.token.consumer.BooleanConsumer
;
import
com.virjar.superappium.xpath.parser.expression.token.consumer.DefaultWordConsumer
;
import
com.virjar.superappium.xpath.parser.expression.token.consumer.DefaultXpathConsumer
;
import
com.virjar.superappium.xpath.parser.expression.token.consumer.DigitConsumer
;
import
com.virjar.superappium.xpath.parser.expression.token.consumer.ExpressionConsumer
;
import
com.virjar.superappium.xpath.parser.expression.token.consumer.FunctionConsumer
;
import
com.virjar.superappium.xpath.parser.expression.token.consumer.OperatorConsumer
;
import
com.virjar.superappium.xpath.parser.expression.token.consumer.StringConstantConsumer
;
import
com.virjar.superappium.xpath.parser.expression.token.consumer.XpathConsumer
;
import
com.virjar.superappium.xpath.parser.expression.token.handler.AttributeHandler
;
import
com.virjar.superappium.xpath.parser.expression.token.handler.BooleanHandler
;
import
com.virjar.superappium.xpath.parser.expression.token.handler.ConstantHandler
;
import
com.virjar.superappium.xpath.parser.expression.token.handler.ExpressionHandler
;
import
com.virjar.superappium.xpath.parser.expression.token.handler.FunctionHandler
;
import
com.virjar.superappium.xpath.parser.expression.token.handler.NumberHandler
;
import
com.virjar.superappium.xpath.parser.expression.token.handler.XpathHandler
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.TreeSet
;
public
class
TokenAnalysisRegistry
{
private
static
TreeSet
<
TokenConsumerWrapper
>
allConsumer
=
new
TreeSet
<>();
private
static
Map
<
String
,
TokenHandler
>
allHandler
=
new
HashMap
<>();
static
{
registerHandler
(
new
AttributeHandler
());
registerHandler
(
new
BooleanHandler
());
registerHandler
(
new
ConstantHandler
());
registerHandler
(
new
FunctionHandler
());
registerHandler
(
new
NumberHandler
());
registerHandler
(
new
XpathHandler
());
registerHandler
(
new
ExpressionHandler
());
registerConsumer
(
new
OperatorConsumer
());
// 40 指定字符开头 div(23) 可以理解为一个函数,也可以理解为一个除法运算,这种歧义不解决了
registerConsumer
(
new
DigitConsumer
());
// 50 数字开头
registerConsumer
(
new
FunctionConsumer
());
// 60 identify开头,紧随左括号,和一般字母可能冲突
registerConsumer
(
new
BooleanConsumer
());
// 70 true,false
// 下面的token不会冲突
registerConsumer
(
new
AttributeActionConsumer
());
// 10 @开头
registerConsumer
(
new
StringConstantConsumer
());
// 30 单号开头
registerConsumer
(
new
XpathConsumer
());
// 20 反引号开头
registerConsumer
(
new
ExpressionConsumer
());
// 0 括号开头
// TODO
registerConsumer
(
new
DefaultWordConsumer
());
registerConsumer
(
new
DefaultXpathConsumer
());
}
public
static
void
registerHandler
(
TokenHandler
tokenHandler
)
{
if
(
Token
.
OPERATOR
.
equals
(
tokenHandler
.
typeName
())
&&
allHandler
.
containsKey
(
Token
.
OPERATOR
))
{
throw
new
IllegalStateException
(
"can not register operator handler,operator handler must hold by framework"
);
}
allHandler
.
put
(
tokenHandler
.
typeName
(),
tokenHandler
);
}
/**
* @param tokenConsumer token识别器
* @see OperatorEnv#addOperator(java.lang.String, int, java.lang.Class)
*/
public
static
void
registerConsumer
(
TokenConsumer
tokenConsumer
)
{
// operator是特殊逻辑,他应该由系统解析,外部不能知道如何构建语法树,所以操作符的语法节点管理权由框架持有,
// 第三方如需扩展,可以通过扩展操作符的方式,注册操作符的运算逻辑即可
if
(!
Token
.
OPERATOR
.
equals
(
tokenConsumer
.
tokenType
())
&&
!
allHandler
.
containsKey
(
tokenConsumer
.
tokenType
()))
{
throw
new
IllegalStateException
(
"can not register token consumer ,not token handler available"
);
}
allConsumer
.
add
(
new
TokenConsumerWrapper
(
tokenConsumer
));
}
public
static
TokenHandler
findHandler
(
String
tokenType
)
{
return
allHandler
.
get
(
tokenType
);
}
public
static
Iterable
<?
extends
TokenConsumer
>
consumerIterable
()
{
return
allConsumer
;
}
private
static
class
TokenConsumerWrapper
implements
Comparable
<
TokenConsumer
>,
TokenConsumer
{
private
TokenConsumer
delegate
;
TokenConsumerWrapper
(
TokenConsumer
delegate
)
{
this
.
delegate
=
delegate
;
}
@Override
public
String
consume
(
TokenQueue
tokenQueue
)
{
return
delegate
.
consume
(
tokenQueue
);
}
@Override
public
int
order
()
{
return
delegate
.
order
();
}
@Override
public
String
tokenType
()
{
return
delegate
.
tokenType
();
}
@Override
public
int
compareTo
(
TokenConsumer
o
)
{
if
(
this
==
o
)
{
return
0
;
}
return
Integer
.
valueOf
(
delegate
.
order
()).
compareTo
(
o
.
order
());
}
}
}
\ No newline at end of file
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/TokenConsumer.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
public
interface
TokenConsumer
{
String
consume
(
TokenQueue
tokenQueue
);
int
order
();
String
tokenType
();
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/TokenHandler.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
;
import
com.virjar.superappium.xpath.exception.XpathSyntaxErrorException
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
public
interface
TokenHandler
{
SyntaxNode
parseToken
(
String
tokenStr
)
throws
XpathSyntaxErrorException
;
String
typeName
();
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/consumer/AttributeActionConsumer.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
consumer
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenConsumer
;
public
class
AttributeActionConsumer
implements
TokenConsumer
{
@Override
public
String
consume
(
TokenQueue
tokenQueue
)
{
if
(
tokenQueue
.
matches
(
"@"
))
{
tokenQueue
.
advance
();
return
tokenQueue
.
consumeAttributeKey
();
}
return
null
;
}
@Override
public
int
order
()
{
return
10
;
}
@Override
public
String
tokenType
()
{
return
Token
.
ATTRIBUTE_ACTION
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/consumer/BooleanConsumer.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
consumer
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenConsumer
;
public
class
BooleanConsumer
implements
TokenConsumer
{
@Override
public
String
consume
(
TokenQueue
tokenQueue
)
{
if
(
tokenQueue
.
matchesBoolean
())
{
return
tokenQueue
.
consumeWord
();
}
return
null
;
}
@Override
public
int
order
()
{
return
70
;
}
@Override
public
String
tokenType
()
{
return
Token
.
BOOLEAN
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/consumer/DefaultWordConsumer.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
consumer
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenConsumer
;
public
class
DefaultWordConsumer
implements
TokenConsumer
{
@Override
public
String
consume
(
TokenQueue
tokenQueue
)
{
if
(
tokenQueue
.
matchesWord
())
{
return
tokenQueue
.
consumeWord
();
}
return
null
;
}
@Override
public
int
order
()
{
return
90
;
}
@Override
public
String
tokenType
()
{
return
Token
.
CONSTANT
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/consumer/DefaultXpathConsumer.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
consumer
;
import
com.virjar.superappium.util.StringUtils
;
import
com.virjar.superappium.xpath.XpathParser
;
import
com.virjar.superappium.xpath.exception.XpathSyntaxErrorException
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenConsumer
;
public
class
DefaultXpathConsumer
implements
TokenConsumer
{
@Override
public
String
consume
(
TokenQueue
tokenQueue
)
{
String
s
=
tokenQueue
.
tryConsumeTo
(
" "
);
if
(
StringUtils
.
isEmpty
(
s
))
{
return
null
;
}
try
{
XpathParser
.
compile
(
s
);
return
tokenQueue
.
consumeTo
(
" "
);
}
catch
(
XpathSyntaxErrorException
e
)
{
// log.debug("exception when compile xpath:{}", s, e);
// TODO
// ignore,根据约定,如果发生异常,则忽略本次调用
return
null
;
}
}
@Override
public
int
order
()
{
return
80
;
}
@Override
public
String
tokenType
()
{
return
Token
.
XPATH
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/consumer/DigitConsumer.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
consumer
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenConsumer
;
public
class
DigitConsumer
implements
TokenConsumer
{
@Override
public
String
consume
(
TokenQueue
tokenQueue
)
{
// 当前遇到的串是一个数字
if
(
tokenQueue
.
matchesDigit
())
{
return
tokenQueue
.
consumeDigit
();
}
return
null
;
}
@Override
public
int
order
()
{
return
50
;
}
@Override
public
String
tokenType
()
{
return
Token
.
NUMBER
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/consumer/ExpressionConsumer.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
consumer
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenConsumer
;
public
class
ExpressionConsumer
implements
TokenConsumer
{
@Override
public
String
consume
(
TokenQueue
tokenQueue
)
{
// 当前遇到的串是一个括号
if
(
tokenQueue
.
matches
(
"("
))
{
// 括号优先级,单独处理,不在逆波兰式内部处理括号问题了,这样逻辑简单一些,而且也浪费不了太大的计算消耗
return
tokenQueue
.
chompBalanced
(
'('
,
')'
);
}
return
null
;
}
@Override
public
int
order
()
{
return
0
;
}
@Override
public
String
tokenType
()
{
return
Token
.
EXPRESSION
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/consumer/FunctionConsumer.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
consumer
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenConsumer
;
public
class
FunctionConsumer
implements
TokenConsumer
{
@Override
public
String
consume
(
TokenQueue
tokenQueue
)
{
if
(
tokenQueue
.
matchesFunction
())
{
return
tokenQueue
.
consumeFunction
();
}
return
null
;
}
@Override
public
int
order
()
{
return
60
;
}
@Override
public
String
tokenType
()
{
return
Token
.
FUNCTION
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/consumer/OperatorConsumer.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
consumer
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.OperatorEnv
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenConsumer
;
import
java.util.List
;
public
class
OperatorConsumer
implements
TokenConsumer
{
@Override
public
String
consume
(
TokenQueue
tokenQueue
)
{
List
<
OperatorEnv
.
AlgorithmHolder
>
algorithmHolders
=
OperatorEnv
.
allAlgorithmUnitList
();
for
(
OperatorEnv
.
AlgorithmHolder
holder
:
algorithmHolders
)
{
if
(
tokenQueue
.
matches
(
holder
.
getKey
()))
{
tokenQueue
.
consume
(
holder
.
getKey
());
return
holder
.
getKey
();
}
}
return
null
;
}
@Override
public
int
order
()
{
return
40
;
}
@Override
public
String
tokenType
()
{
return
Token
.
OPERATOR
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/consumer/StringConstantConsumer.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
consumer
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenConsumer
;
public
class
StringConstantConsumer
implements
TokenConsumer
{
@Override
public
String
consume
(
TokenQueue
tokenQueue
)
{
if
(
tokenQueue
.
matches
(
"\'"
))
{
return
TokenQueue
.
unescape
(
tokenQueue
.
chompBalanced
(
'\''
,
'\''
));
}
else
if
(
tokenQueue
.
matches
(
"\""
))
{
return
TokenQueue
.
unescape
(
tokenQueue
.
chompBalanced
(
'\"'
,
'\"'
));
}
return
null
;
}
@Override
public
int
order
()
{
return
30
;
}
@Override
public
String
tokenType
()
{
return
Token
.
CONSTANT
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/consumer/XpathConsumer.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
consumer
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenConsumer
;
public
class
XpathConsumer
implements
TokenConsumer
{
@Override
public
String
consume
(
TokenQueue
tokenQueue
)
{
// xpath子串
if
(
tokenQueue
.
matches
(
"`"
))
{
return
tokenQueue
.
chompBalanced
(
'`'
,
'`'
);
}
return
null
;
}
@Override
public
int
order
()
{
return
20
;
}
@Override
public
String
tokenType
()
{
return
Token
.
XPATH
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/handler/AttributeHandler.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
handler
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenHandler
;
public
class
AttributeHandler
implements
TokenHandler
{
@Override
public
SyntaxNode
parseToken
(
final
String
tokenStr
)
{
return
element
->
element
.
attribute
(
tokenStr
);
}
@Override
public
String
typeName
()
{
return
Token
.
ATTRIBUTE_ACTION
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/handler/BooleanHandler.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
handler
;
import
com.virjar.superappium.util.Lists
;
import
com.virjar.superappium.xpath.exception.XpathSyntaxErrorException
;
import
com.virjar.superappium.xpath.function.FunctionEnv
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
import
com.virjar.superappium.xpath.parser.expression.node.FunctionNode
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenHandler
;
public
class
BooleanHandler
implements
TokenHandler
{
@Override
public
SyntaxNode
parseToken
(
final
String
tokenStr
)
throws
XpathSyntaxErrorException
{
return
new
FunctionNode
(
FunctionEnv
.
getFilterFunction
(
BooleanUtils
.
toBoolean
(
tokenStr
)
?
"true"
:
"false"
),
Lists
.<
SyntaxNode
>
newLinkedList
());
}
@Override
public
String
typeName
()
{
return
Token
.
BOOLEAN
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/handler/ConstantHandler.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
handler
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenHandler
;
public
class
ConstantHandler
implements
TokenHandler
{
@Override
public
SyntaxNode
parseToken
(
final
String
tokenStr
)
{
return
new
SyntaxNode
()
{
@Override
public
Object
calc
(
ViewImage
element
)
{
return
tokenStr
;
}
};
}
@Override
public
String
typeName
()
{
return
Token
.
CONSTANT
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/handler/ExpressionHandler.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
handler
;
import
com.virjar.superappium.xpath.exception.XpathSyntaxErrorException
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.ExpressionParser
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenHandler
;
/**
* Created by virjar on 17/6/12.
*/
public
class
ExpressionHandler
implements
TokenHandler
{
@Override
public
SyntaxNode
parseToken
(
String
tokenStr
)
throws
XpathSyntaxErrorException
{
return
new
ExpressionParser
(
new
TokenQueue
(
tokenStr
)).
parse
();
}
@Override
public
String
typeName
()
{
return
Token
.
EXPRESSION
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/handler/FunctionHandler.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
handler
;
import
com.virjar.superappium.xpath.exception.XpathSyntaxErrorException
;
import
com.virjar.superappium.xpath.parser.TokenQueue
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenHandler
;
public
class
FunctionHandler
implements
TokenHandler
{
@Override
public
SyntaxNode
parseToken
(
String
tokenStr
)
throws
XpathSyntaxErrorException
{
return
new
FunctionParser
(
new
TokenQueue
(
tokenStr
)).
parse
();
}
@Override
public
String
typeName
()
{
return
Token
.
FUNCTION
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/handler/NumberHandler.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
handler
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.util.StringUtils
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenHandler
;
public
class
NumberHandler
implements
TokenHandler
{
@Override
public
SyntaxNode
parseToken
(
final
String
tokenStr
)
{
return
new
SyntaxNode
()
{
@Override
public
Object
calc
(
ViewImage
element
)
{
if
(
StringUtils
.
contains
(
tokenStr
,
"."
))
{
return
NumberUtils
.
toDouble
(
tokenStr
);
}
else
{
return
NumberUtils
.
toInt
(
tokenStr
);
}
}
\
};
}
@Override
public
String
typeName
()
{
return
Token
.
NUMBER
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/parser/expression/token/handler/XpathHandler.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
parser
.
expression
.
token
.
handler
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.XpathParser
;
import
com.virjar.superappium.xpath.exception.XpathSyntaxErrorException
;
import
com.virjar.superappium.xpath.model.XNode
;
import
com.virjar.superappium.xpath.model.XNodes
;
import
com.virjar.superappium.xpath.model.XpathEvaluator
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
import
com.virjar.superappium.xpath.parser.expression.token.Token
;
import
com.virjar.superappium.xpath.parser.expression.token.TokenHandler
;
public
class
XpathHandler
implements
TokenHandler
{
@Override
public
SyntaxNode
parseToken
(
String
tokenStr
)
throws
XpathSyntaxErrorException
{
final
XpathEvaluator
xpathEvaluator
=
new
XpathParser
(
tokenStr
).
parse
();
return
new
SyntaxNode
()
{
@Override
public
Object
calc
(
ViewImage
element
)
{
return
xpathEvaluator
.
evaluate
(
new
XNodes
(
XNode
.
e
(
element
)));
}
};
}
@Override
public
String
typeName
()
{
return
Token
.
XPATH
;
}
}
super-appium/src/main/java/com/virjar/superappium/xpath/util/XpathUtil.java
0 → 100644
View file @
c352e39c
package
com
.
virjar
.
superappium
.
xpath
.
util
;
import
com.virjar.superappium.ViewImage
;
import
com.virjar.superappium.xpath.exception.EvaluateException
;
import
com.virjar.superappium.xpath.model.XNode
;
import
com.virjar.superappium.xpath.parser.expression.SyntaxNode
;
import
java.math.BigDecimal
;
import
java.util.LinkedList
;
import
java.util.List
;
public
class
XpathUtil
{
public
static
List
<
ViewImage
>
transformToElement
(
List
<
XNode
>
input
)
{
List
<
ViewImage
>
ret
=
new
LinkedList
<>();
for
(
XNode
xNode
:
input
)
{
if
(!
xNode
.
isText
())
{
ret
.
add
(
xNode
.
getElement
());
}
}
return
ret
;
}
public
static
String
toPlainString
(
Object
obj
)
{
if
(
obj
==
null
)
{
return
"null"
;
}
return
obj
.
toString
();
}
public
static
BigDecimal
toBigDecimal
(
Number
number
)
{
if
(
number
instanceof
BigDecimal
)
{
return
(
BigDecimal
)
number
;
}
if
(
number
instanceof
Integer
)
{
return
new
BigDecimal
(
number
.
intValue
());
}
if
(
number
instanceof
Double
||
number
instanceof
Float
)
{
// BigDecimal float 也是转double
return
new
BigDecimal
(
number
.
doubleValue
());
}
if
(
number
instanceof
Long
)
{
return
BigDecimal
.
valueOf
(
number
.
longValue
());
}
return
new
BigDecimal
(
number
.
toString
());
}
public
static
Integer
firstParamToInt
(
List
<
SyntaxNode
>
params
,
ViewImage
element
,
String
functionName
)
{
if
(
params
.
size
()
>
0
)
{
Object
calc
=
params
.
get
(
0
).
calc
(
element
);
if
(
calc
!=
null
&&
!(
calc
instanceof
Integer
))
{
throw
new
EvaluateException
(
functionName
+
" parameter must be integer"
);
}
else
{
if
(
calc
!=
null
)
{
return
(
Integer
)
calc
;
}
}
}
return
null
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment