@ -58,9 +58,9 @@ public class Criteria implements Predicate {
private static enum CriteriaType {
private static enum CriteriaType {
EQ {
EQ {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
boolean res = ( 0 = = safeCompare ( left , right ) ) ;
boolean res = ( 0 = = safeCompare ( expected , model ) ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , right , name ( ) , left , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , model , name ( ) , expected , res ) ;
return res ;
return res ;
}
}
@ -71,9 +71,9 @@ public class Criteria implements Predicate {
} ,
} ,
NE {
NE {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
boolean res = ( 0 ! = safeCompare ( left , right ) ) ;
boolean res = ( 0 ! = safeCompare ( expected , model ) ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , right , name ( ) , left , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , model , name ( ) , expected , res ) ;
return res ;
return res ;
}
}
@ -84,14 +84,15 @@ public class Criteria implements Predicate {
} ,
} ,
GT {
GT {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
if ( ( left = = null ) ^ ( right = = null ) ) {
if ( ( expected = = null ) ^ ( model = = null ) ) {
return false ;
return false ;
}
}
boolean res = ( 0 > safeCompare ( left , right ) ) ;
boolean res = ( 0 > safeCompare ( expected , model ) ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , right , name ( ) , left , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , model , name ( ) , expected , res ) ;
return res ;
return res ;
}
}
@Override
@Override
public String toString ( ) {
public String toString ( ) {
return ">" ;
return ">" ;
@ -99,14 +100,15 @@ public class Criteria implements Predicate {
} ,
} ,
GTE {
GTE {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
if ( ( left = = null ) ^ ( right = = null ) ) {
if ( ( expected = = null ) ^ ( model = = null ) ) {
return false ;
return false ;
}
}
boolean res = ( 0 > = safeCompare ( left , right ) ) ;
boolean res = ( 0 > = safeCompare ( expected , model ) ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , right , name ( ) , left , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , model , name ( ) , expected , res ) ;
return res ;
return res ;
}
}
@Override
@Override
public String toString ( ) {
public String toString ( ) {
return ">=" ;
return ">=" ;
@ -114,14 +116,15 @@ public class Criteria implements Predicate {
} ,
} ,
LT {
LT {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
if ( ( left = = null ) ^ ( right = = null ) ) {
if ( ( expected = = null ) ^ ( model = = null ) ) {
return false ;
return false ;
}
}
boolean res = ( 0 < safeCompare ( left , right ) ) ;
boolean res = ( 0 < safeCompare ( expected , model ) ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , right , name ( ) , left , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , model , name ( ) , expected , res ) ;
return res ;
return res ;
}
}
@Override
@Override
public String toString ( ) {
public String toString ( ) {
return "<" ;
return "<" ;
@ -129,14 +132,15 @@ public class Criteria implements Predicate {
} ,
} ,
LTE {
LTE {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
if ( ( left = = null ) ^ ( right = = null ) ) {
if ( ( expected = = null ) ^ ( model = = null ) ) {
return false ;
return false ;
}
}
boolean res = ( 0 < = safeCompare ( left , right ) ) ;
boolean res = ( 0 < = safeCompare ( expected , model ) ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , right , name ( ) , left , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , model , name ( ) , expected , res ) ;
return res ;
return res ;
}
}
@Override
@Override
public String toString ( ) {
public String toString ( ) {
return "<=" ;
return "<=" ;
@ -144,37 +148,59 @@ public class Criteria implements Predicate {
} ,
} ,
IN {
IN {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
boolean res = false ;
boolean res = false ;
Collection exps = ( Collection ) left ;
Collection exps = ( Collection ) expected ;
for ( Object exp : exps ) {
for ( Object exp : exps ) {
if ( 0 = = safeCompare ( exp , right ) ) {
if ( 0 = = safeCompare ( exp , model ) ) {
res = true ;
res = true ;
break ;
break ;
}
}
}
}
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , right , name ( ) , join ( ", " , exps ) , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , model , name ( ) , join ( ", " , exps ) , res ) ;
return res ;
return res ;
}
}
} ,
} ,
NIN {
NIN {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
Collection nexps = ( Collection ) left ;
Collection nexps = ( Collection ) expected ;
boolean res = ! nexps . contains ( right ) ;
boolean res = ! nexps . contains ( model ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , right , name ( ) , join ( ", " , nexps ) , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , model , name ( ) , join ( ", " , nexps ) , res ) ;
return res ;
}
} ,
CONTAINS {
@Override
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
boolean res = false ;
if ( ctx . configuration ( ) . jsonProvider ( ) . isArray ( model ) ) {
for ( Object o : ctx . configuration ( ) . jsonProvider ( ) . toIterable ( model ) ) {
if ( expected . equals ( o ) ) {
res = true ;
break ;
}
}
} else if ( model instanceof String ) {
if ( isNullish ( expected ) | | ! ( expected instanceof String ) ) {
res = false ;
} else {
res = ( ( String ) model ) . contains ( ( String ) expected ) ;
}
}
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , model , name ( ) , expected , res ) ;
return res ;
return res ;
}
}
} ,
} ,
ALL {
ALL {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
boolean res = true ;
boolean res = true ;
Collection exps = ( Collection ) left ;
Collection exps = ( Collection ) expected ;
if ( ctx . configuration ( ) . jsonProvider ( ) . isArray ( right ) ) {
if ( ctx . configuration ( ) . jsonProvider ( ) . isArray ( model ) ) {
for ( Object exp : exps ) {
for ( Object exp : exps ) {
boolean found = false ;
boolean found = false ;
for ( Object check : ctx . configuration ( ) . jsonProvider ( ) . toIterable ( right ) ) {
for ( Object check : ctx . configuration ( ) . jsonProvider ( ) . toIterable ( model ) ) {
if ( 0 = = safeCompare ( exp , check ) ) {
if ( 0 = = safeCompare ( exp , check ) ) {
found = true ;
found = true ;
break ;
break ;
@ -185,7 +211,8 @@ public class Criteria implements Predicate {
break ;
break ;
}
}
}
}
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , join ( ", " , ctx . configuration ( ) . jsonProvider ( ) . toIterable ( right ) ) , name ( ) , join ( ", " , exps ) , res ) ;
if ( logger . isDebugEnabled ( ) )
logger . debug ( "[{}] {} [{}] => {}" , join ( ", " , ctx . configuration ( ) . jsonProvider ( ) . toIterable ( model ) ) , name ( ) , join ( ", " , exps ) , res ) ;
} else {
} else {
res = false ;
res = false ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , "<NOT AN ARRAY>" , name ( ) , join ( ", " , exps ) , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , "<NOT AN ARRAY>" , name ( ) , join ( ", " , exps ) , res ) ;
@ -195,61 +222,64 @@ public class Criteria implements Predicate {
} ,
} ,
SIZE {
SIZE {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
int size = ( Integer ) left ;
int size = ( Integer ) expected ;
boolean res ;
boolean res ;
if ( ctx . configuration ( ) . jsonProvider ( ) . isArray ( right ) ) {
if ( ctx . configuration ( ) . jsonProvider ( ) . isArray ( model ) ) {
int length = ctx . configuration ( ) . jsonProvider ( ) . length ( right ) ;
int length = ctx . configuration ( ) . jsonProvider ( ) . length ( model ) ;
res = ( length = = size ) ;
res = ( length = = size ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "Array with size {} {} {} => {}" , length , name ( ) , size , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "Array with size {} {} {} => {}" , length , name ( ) , size , res ) ;
} else if ( right instanceof String ) {
} else if ( model instanceof String ) {
int length = ( ( String ) right ) . length ( ) ;
int length = ( ( String ) model ) . length ( ) ;
res = length = = size ;
res = length = = size ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "String with length {} {} {} => {}" , length , name ( ) , size , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "String with length {} {} {} => {}" , length , name ( ) , size , res ) ;
} else {
} else {
res = false ;
res = false ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "{} {} {} => {}" , right = = null ? "null" : right . getClass ( ) . getName ( ) , name ( ) , size , res ) ;
if ( logger . isDebugEnabled ( ) )
logger . debug ( "{} {} {} => {}" , model = = null ? "null" : model . getClass ( ) . getName ( ) , name ( ) , size , res ) ;
}
}
return res ;
return res ;
}
}
} ,
} ,
EXISTS {
EXISTS {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
//This must be handled outside
//This must be handled outside
throw new UnsupportedOperationException ( ) ;
throw new UnsupportedOperationException ( ) ;
}
}
} ,
} ,
TYPE {
TYPE {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
final Class < ? > expType = ( Class < ? > ) left ;
final Class < ? > expType = ( Class < ? > ) expected ;
final Class < ? > actType = right = = null ? null : right . getClass ( ) ;
final Class < ? > actType = model = = null ? null : model . getClass ( ) ;
return actType ! = null & & expType . isAssignableFrom ( actType ) ;
return actType ! = null & & expType . isAssignableFrom ( actType ) ;
}
}
} ,
} ,
REGEX {
REGEX {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
boolean res = false ;
boolean res = false ;
Pattern pattern ;
Pattern pattern ;
Object target ;
Object target ;
if ( right instanceof Pattern ) {
if ( model instanceof Pattern ) {
pattern = ( Pattern ) right ;
pattern = ( Pattern ) model ;
target = left ;
target = expected ;
} else {
} else {
pattern = ( Pattern ) left ;
pattern = ( Pattern ) expected ;
target = right ;
target = model ;
}
}
if ( target ! = null ) {
if ( target ! = null ) {
res = pattern . matcher ( target . toString ( ) ) . matches ( ) ;
res = pattern . matcher ( target . toString ( ) ) . matches ( ) ;
}
}
if ( logger . isDebugEnabled ( ) ) logger . debug ( "[{}] {} [{}] => {}" , right = = null ? "null" : right . toString ( ) , name ( ) , left = = null ? "null" : left . toString ( ) , res ) ;
if ( logger . isDebugEnabled ( ) )
logger . debug ( "[{}] {} [{}] => {}" , model = = null ? "null" : model . toString ( ) , name ( ) , expected = = null ? "null" : expected . toString ( ) , res ) ;
return res ;
return res ;
}
}
@Override
@Override
public String toString ( ) {
public String toString ( ) {
return "=~" ;
return "=~" ;
@ -257,23 +287,23 @@ public class Criteria implements Predicate {
} ,
} ,
MATCHES {
MATCHES {
@Override
@Override
boolean eval ( Object left , final Object right , final PredicateContext ctx ) {
boolean eval ( Object expected , final Object model , final PredicateContext ctx ) {
PredicateContextImpl pci = ( PredicateContextImpl ) ctx ;
PredicateContextImpl pci = ( PredicateContextImpl ) ctx ;
Predicate exp = ( Predicate ) left ;
Predicate exp = ( Predicate ) expected ;
return exp . apply ( new PredicateContextImpl ( right , ctx . root ( ) , ctx . configuration ( ) , pci . documentPathCache ( ) ) ) ;
return exp . apply ( new PredicateContextImpl ( model , ctx . root ( ) , ctx . configuration ( ) , pci . documentPathCache ( ) ) ) ;
}
}
} ,
} ,
NOT_EMPTY {
NOT_EMPTY {
@Override
@Override
boolean eval ( Object left , Object right , PredicateContext ctx ) {
boolean eval ( Object expected , Object model , PredicateContext ctx ) {
boolean res = false ;
boolean res = false ;
if ( right ! = null ) {
if ( model ! = null ) {
if ( ctx . configuration ( ) . jsonProvider ( ) . isArray ( right ) ) {
if ( ctx . configuration ( ) . jsonProvider ( ) . isArray ( model ) ) {
int len = ctx . configuration ( ) . jsonProvider ( ) . length ( right ) ;
int len = ctx . configuration ( ) . jsonProvider ( ) . length ( model ) ;
res = ( 0 ! = len ) ;
res = ( 0 ! = len ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "array length = {} {} => {}" , len , name ( ) , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "array length = {} {} => {}" , len , name ( ) , res ) ;
} else if ( right instanceof String ) {
} else if ( model instanceof String ) {
int len = ( ( String ) right ) . length ( ) ;
int len = ( ( String ) model ) . length ( ) ;
res = ( 0 ! = len ) ;
res = ( 0 ! = len ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "string length = {} {} => {}" , len , name ( ) , res ) ;
if ( logger . isDebugEnabled ( ) ) logger . debug ( "string length = {} {} => {}" , len , name ( ) , res ) ;
}
}
@ -282,7 +312,7 @@ public class Criteria implements Predicate {
}
}
} ;
} ;
abstract boolean eval ( Object left , Object right , PredicateContext ctx ) ;
abstract boolean eval ( Object expected , Object model , PredicateContext ctx ) ;
public static CriteriaType parse ( String str ) {
public static CriteriaType parse ( String str ) {
if ( "==" . equals ( str ) ) {
if ( "==" . equals ( str ) ) {
@ -306,12 +336,12 @@ public class Criteria implements Predicate {
}
}
private Criteria ( List < Criteria > criteriaChain , Object left ) {
private Criteria ( List < Criteria > criteriaChain , Object left ) {
/ *
if ( left instanceof Path ) {
if ( left instanceof Path ) {
if ( ! ( ( Path ) left ) . isDefinite ( ) ) {
if ( ! ( ( Path ) left ) . isDefinite ( ) ) {
throw new InvalidCriteriaException ( "A criteria path must be definite. The path " + left . toString ( ) + " is not!" ) ;
throw new InvalidCriteriaException ( "A criteria path must be definite. The path " + left . toString ( ) + " is not!" ) ;
}
}
}
} * /
this . left = left ;
this . left = left ;
this . criteriaChain = criteriaChain ;
this . criteriaChain = criteriaChain ;
this . criteriaChain . add ( this ) ;
this . criteriaChain . add ( this ) ;
@ -542,6 +572,19 @@ public class Criteria implements Predicate {
return this ;
return this ;
}
}
/ * *
* The < code > contains < / code > operator asserts that the provided object is contained
* in the result . The object that should contain the input can be either an object or a String .
*
* @param o that should exists in given collection or
* @return the criteria
* /
public Criteria contains ( Object o ) {
this . criteriaType = CriteriaType . CONTAINS ;
this . right = o ;
return this ;
}
/ * *
/ * *
* The < code > nin < / code > operator is similar to $in except that it selects objects for
* The < code > nin < / code > operator is similar to $in except that it selects objects for
* which the specified field does not have any value in the specified array .
* which the specified field does not have any value in the specified array .
@ -666,6 +709,7 @@ public class Criteria implements Predicate {
private static boolean isString ( String string ) {
private static boolean isString ( String string ) {
return ( string ! = null & & ! string . isEmpty ( ) & & string . charAt ( 0 ) = = '\'' & & string . charAt ( string . length ( ) - 1 ) = = '\'' ) ;
return ( string ! = null & & ! string . isEmpty ( ) & & string . charAt ( 0 ) = = '\'' & & string . charAt ( string . length ( ) - 1 ) = = '\'' ) ;
}
}
private static boolean isPattern ( String string ) {
private static boolean isPattern ( String string ) {
return ( string ! = null
return ( string ! = null
& & ! string . isEmpty ( )
& & ! string . isEmpty ( )
@ -684,9 +728,9 @@ public class Criteria implements Predicate {
}
}
/ * *
/ * *
* Parse the provided criteria
* Parse the provided criteria
*
* @param criteria
* @param criteria
* @return a criteria
* @return a criteria
* /
* /
@ -713,6 +757,7 @@ public class Criteria implements Predicate {
/ * *
/ * *
* Creates a new criteria
* Creates a new criteria
*
* @param left path to evaluate in criteria
* @param left path to evaluate in criteria
* @param operator operator
* @param operator operator
* @param right expected value
* @param right expected value
@ -807,16 +852,12 @@ public class Criteria implements Predicate {
}
}
@Override
@Override
public String toString ( ) {
public String toString ( ) {
StringBuilder sb = new StringBuilder ( ) ;
StringBuilder sb = new StringBuilder ( ) ;
sb . append ( left . toString ( ) )
sb . append ( left . toString ( ) )
//.append("|")
. append ( criteriaType . toString ( ) )
. append ( criteriaType . toString ( ) )
//.append("|")
. append ( wrapString ( right ) ) ;
. append ( wrapString ( right ) ) ;
//.append("|");
return sb . toString ( ) ;
return sb . toString ( ) ;
}
}
@ -832,6 +873,4 @@ public class Criteria implements Predicate {
}
}
}
}