JSONPathFilter.java
package com.alibaba.fastjson2;
import com.alibaba.fastjson2.util.IOUtils;
import com.alibaba.fastjson2.writer.FieldWriter;
import com.alibaba.fastjson2.writer.ObjectWriter;
import com.alibaba.fastjson2.writer.ObjectWriterAdapter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
abstract class JSONPathFilter
extends JSONPathSegment
implements JSONPathSegment.EvalSegment {
private boolean and = true;
public boolean isAnd() {
return and;
}
public JSONPathFilter setAnd(boolean and) {
this.and = and;
return this;
}
abstract boolean apply(JSONPath.Context context, Object object);
enum Operator {
EQ,
NE,
GT,
GE,
LT,
LE,
LIKE,
NOT_LIKE,
RLIKE,
NOT_RLIKE,
IN,
NOT_IN,
BETWEEN,
NOT_BETWEEN,
AND,
OR,
REG_MATCH,
STARTS_WITH,
ENDS_WITH,
CONTAINS,
NOT_CONTAINS;
public String toString() {
switch (this) {
case EQ:
return "==";
case NE:
return "!=";
case GT:
return ">";
case GE:
return ">=";
case LT:
return "<";
case LE:
return "<=";
case LIKE:
return "like";
case NOT_LIKE:
return "not like";
case RLIKE:
return "rlike";
case NOT_RLIKE:
return "not rlike";
case BETWEEN:
return "between";
case NOT_BETWEEN:
return "not between";
case AND:
return "and";
case OR:
return "or";
case STARTS_WITH:
return "starts with";
case ENDS_WITH:
return "ends with";
case CONTAINS:
return "contains";
case NOT_CONTAINS:
return "not contains";
default:
return name();
}
}
}
static final class NameIsNull
extends NameFilter {
public NameIsNull(
String fieldName,
long fieldNameNameHash,
String[] fieldName2,
long[] fieldNameNameHash2,
Function function
) {
super(fieldName, fieldNameNameHash, fieldName2, fieldNameNameHash2, function);
}
protected boolean applyNull() {
return true;
}
@Override
boolean apply(Object fieldValue) {
if (function != null) {
fieldValue = function.apply(fieldValue);
}
return fieldValue == null;
}
}
static final class NameIntOpSegment
extends NameFilter {
final Operator operator;
final long value;
public NameIntOpSegment(
String name,
long nameHashCode,
String[] fieldName2,
long[] fieldNameNameHash2,
Function expr,
Operator operator,
long value) {
super(name, nameHashCode, fieldName2, fieldNameNameHash2, expr);
this.operator = operator;
this.value = value;
}
@Override
protected boolean applyNull() {
return operator == Operator.NE;
}
@Override
public boolean apply(Object fieldValue) {
boolean objInt = fieldValue instanceof Boolean
|| fieldValue instanceof Byte
|| fieldValue instanceof Short
|| fieldValue instanceof Integer
|| fieldValue instanceof Long;
if (objInt) {
long fieldValueInt;
if (fieldValue instanceof Boolean) {
fieldValueInt = (Boolean) fieldValue ? 1 : 0;
} else {
fieldValueInt = ((Number) fieldValue).longValue();
}
switch (operator) {
case LT:
return fieldValueInt < this.value;
case LE:
return fieldValueInt <= this.value;
case EQ:
return fieldValueInt == this.value;
case NE:
return fieldValueInt != this.value;
case GT:
return fieldValueInt > this.value;
case GE:
return fieldValueInt >= this.value;
default:
throw new UnsupportedOperationException();
}
}
int cmp;
if (fieldValue instanceof BigDecimal) {
cmp = ((BigDecimal) fieldValue)
.compareTo(
BigDecimal.valueOf(value));
} else if (fieldValue instanceof BigInteger) {
cmp = ((BigInteger) fieldValue)
.compareTo(
BigInteger.valueOf(value));
} else if (fieldValue instanceof Float) {
cmp = ((Float) fieldValue)
.compareTo(
(float) value);
} else if (fieldValue instanceof Double) {
cmp = ((Double) fieldValue)
.compareTo(
(double) value);
} else if (fieldValue instanceof String) {
String fieldValueStr = (String) fieldValue;
if (IOUtils.isNumber(fieldValueStr)) {
try {
cmp = Long.compare(Long.parseLong(fieldValueStr), value);
} catch (Exception ignored) {
cmp = fieldValueStr.compareTo(Long.toString(value));
}
} else {
cmp = fieldValueStr.compareTo(Long.toString(value));
}
} else {
throw new UnsupportedOperationException();
}
switch (operator) {
case LT:
return cmp < 0;
case LE:
return cmp <= 0;
case EQ:
return cmp == 0;
case NE:
return cmp != 0;
case GT:
return cmp > 0;
case GE:
return cmp >= 0;
default:
throw new UnsupportedOperationException();
}
}
@Override
public void set(JSONPath.Context context, Object value) {
Object object = context.parent == null
? context.root
: context.parent.value;
if (object instanceof List) {
List list = (List) object;
for (int i = 0; i < list.size(); i++) {
Object item = list.get(i);
if (apply(context, item)) {
list.set(i, value);
}
}
return;
}
throw new JSONException("UnsupportedOperation ");
}
public void setCallback(JSONPath.Context context, BiFunction callback) {
Object object = context.parent == null
? context.root
: context.parent.value;
if (object instanceof List) {
List list = (List) object;
for (int i = 0; i < list.size(); i++) {
Object item = list.get(i);
if (apply(context, item)) {
Object value = callback.apply(list, item);
if (value != item) {
list.set(i, value);
}
}
}
return;
}
throw new JSONException("UnsupportedOperation ");
}
@Override
public String toString() {
return "[?("
+ (fieldName2 == null ? "@" : fieldName2)
+ '.'
+ fieldName + ' ' + operator + ' ' + value
+ ")]";
}
}
static final class NameDecimalOpSegment
extends NameFilter {
final Operator operator;
final BigDecimal value;
public NameDecimalOpSegment(String name, long nameHashCode, Operator operator, BigDecimal value) {
super(name, nameHashCode);
this.operator = operator;
this.value = value;
}
protected boolean applyNull() {
return operator == Operator.NE;
}
@Override
public boolean apply(Object fieldValue) {
if (fieldValue == null) {
return false;
}
BigDecimal fieldValueDecimal;
if (fieldValue instanceof Boolean) {
fieldValueDecimal = (Boolean) fieldValue ? BigDecimal.ONE : BigDecimal.ZERO;
} else if (fieldValue instanceof Byte
|| fieldValue instanceof Short
|| fieldValue instanceof Integer
|| fieldValue instanceof Long) {
fieldValueDecimal = BigDecimal.valueOf(
((Number) fieldValue).longValue()
);
} else if (fieldValue instanceof BigDecimal) {
fieldValueDecimal = ((BigDecimal) fieldValue);
} else if (fieldValue instanceof BigInteger) {
fieldValueDecimal = new BigDecimal((BigInteger) fieldValue);
} else {
throw new UnsupportedOperationException();
}
int cmp = fieldValueDecimal.compareTo(value);
switch (operator) {
case LT:
return cmp < 0;
case LE:
return cmp <= 0;
case EQ:
return cmp == 0;
case NE:
return cmp != 0;
case GT:
return cmp > 0;
case GE:
return cmp >= 0;
default:
throw new UnsupportedOperationException();
}
}
}
static final class NameRLikeSegment
extends NameFilter {
final Pattern pattern;
final boolean not;
public NameRLikeSegment(String fieldName, long fieldNameNameHash, Pattern pattern, boolean not) {
super(fieldName, fieldNameNameHash);
this.pattern = pattern;
this.not = not;
}
@Override
boolean apply(Object fieldValue) {
String strPropertyValue = fieldValue.toString();
Matcher m = pattern.matcher(strPropertyValue);
boolean match = m.matches();
if (not) {
match = !match;
}
return match;
}
}
static final class StartsWithSegment
extends NameFilter {
final String prefix;
public StartsWithSegment(String fieldName, long fieldNameNameHash, String prefix) {
super(fieldName, fieldNameNameHash);
this.prefix = prefix;
}
@Override
boolean apply(Object fieldValue) {
String propertyValue = fieldValue.toString();
return propertyValue != null && propertyValue.startsWith(prefix);
}
}
static final class EndsWithSegment
extends NameFilter {
final String prefix;
public EndsWithSegment(String fieldName, long fieldNameNameHash, String prefix) {
super(fieldName, fieldNameNameHash);
this.prefix = prefix;
}
@Override
boolean apply(Object fieldValue) {
String propertyValue = fieldValue.toString();
return propertyValue != null && propertyValue.endsWith(prefix);
}
}
static final class GroupFilter
extends JSONPathSegment
implements EvalSegment {
final List<JSONPathFilter> filters;
public GroupFilter(List<JSONPathFilter> filters) {
this.filters = filters;
}
@Override
public void accept(JSONReader jsonReader, JSONPath.Context context) {
if (context.parent == null) {
context.root = jsonReader.readAny();
}
eval(context);
}
@Override
public void eval(JSONPath.Context context) {
Object object = context.parent == null
? context.root
: context.parent.value;
List<JSONPathFilter> orderedFilters = new ArrayList<>();
if (this.filters != null) {
orderedFilters = this.filters.stream().sorted(Comparator.comparing(JSONPathFilter::isAnd)).collect(Collectors.toList());
}
if (object instanceof List) {
List list = (List) object;
JSONArray array = new JSONArray(list.size());
for (int i = 0; i < list.size(); i++) {
Object item = list.get(i);
boolean match = false;
for (JSONPathFilter filter : orderedFilters) {
boolean and = filter.isAnd();
match = and;
boolean result = filter.apply(context, item);
if (and) {
if (!result) {
match = false;
break;
}
} else {
if (result) {
match = true;
break;
}
}
}
if (match) {
array.add(item);
}
}
context.value = array;
context.eval = true;
return;
}
boolean match = false;
for (JSONPathFilter filter : orderedFilters) {
boolean and = filter.isAnd();
match = and;
boolean result = filter.apply(context, object);
if (and) {
if (!result) {
match = false;
break;
}
} else {
if (result) {
match = true;
break;
}
}
}
if (match) {
context.value = object;
}
context.eval = true;
}
}
abstract static class NameFilter
extends JSONPathFilter {
final String fieldName;
final long fieldNameNameHash;
final String[] fieldName2;
final long[] fieldNameNameHash2;
final Function function;
boolean includeArray = true;
public NameFilter(String fieldName, long fieldNameNameHash) {
this.fieldName = fieldName;
this.fieldNameNameHash = fieldNameNameHash;
this.fieldName2 = null;
this.fieldNameNameHash2 = null;
this.function = null;
}
public NameFilter(
String fieldName,
long fieldNameNameHash,
String[] fieldName2,
long[] fieldNameNameHash2,
Function function
) {
this.fieldName = fieldName;
this.fieldNameNameHash = fieldNameNameHash;
this.fieldName2 = fieldName2;
this.fieldNameNameHash2 = fieldNameNameHash2;
this.function = function;
}
abstract boolean apply(Object fieldValue);
@Override
public final void accept(JSONReader jsonReader, JSONPath.Context context) {
if (context.parent == null) {
context.root = jsonReader.readAny();
}
eval(context);
}
@Override
public boolean remove(JSONPath.Context context) {
Object object = context.parent == null
? context.root
: context.parent.value;
if (object instanceof List) {
List list = (List) object;
for (int i = list.size() - 1; i >= 0; i--) {
Object item = list.get(i);
if (apply(context, item)) {
list.remove(i);
}
}
return true;
}
throw new JSONException("UnsupportedOperation " + getClass());
}
@Override
public final void eval(JSONPath.Context context) {
Object object = context.parent == null
? context.root
: context.parent.value;
if (object instanceof List) {
List list = (List) object;
JSONArray array = new JSONArray(list.size());
for (int i = 0; i < list.size(); i++) {
Object item = list.get(i);
if (apply(context, item)) {
array.add(item);
}
}
context.value = array;
context.eval = true;
return;
}
if (object instanceof Object[]) {
Object[] list = (Object[]) object;
JSONArray array = new JSONArray(list.length);
for (Object item : list) {
if (apply(context, item)) {
array.add(item);
}
}
context.value = array;
context.eval = true;
return;
}
if (object instanceof JSONPath.Sequence) {
JSONPath.Sequence sequence = (JSONPath.Sequence) object;
JSONArray array = new JSONArray();
for (Object value : sequence.values) {
if (includeArray && value instanceof Collection) {
for (Object valueItem : ((Collection<?>) value)) {
if (apply(context, valueItem)) {
array.add(valueItem);
}
}
} else {
if (apply(context, value)) {
array.add(value);
}
}
}
context.value = array;
context.eval = true;
return;
}
if (apply(context, object)) {
context.value = object;
context.eval = true;
}
}
protected boolean applyNull() {
return false;
}
@Override
public final boolean apply(JSONPath.Context context, Object object) {
if (object == null) {
return false;
}
JSONWriter.Context writerContext = context.path.getWriterContext();
if (object instanceof Map) {
Object fieldValue = fieldName == null ? object : ((Map<?, ?>) object).get(fieldName);
if (fieldValue == null) {
return applyNull();
}
if (fieldName2 != null) {
for (int i = 0; i < fieldName2.length; i++) {
String name = fieldName2[i];
if (fieldValue instanceof Map) {
fieldValue = ((Map) fieldValue).get(name);
} else {
ObjectWriter objectWriter2 = writerContext.getObjectWriter(fieldValue.getClass());
if (objectWriter2 instanceof ObjectWriterAdapter) {
FieldWriter fieldWriter2 = objectWriter2.getFieldWriter(fieldNameNameHash2[i]);
if (fieldWriter2 == null) {
return false;
}
fieldValue = fieldWriter2.getFieldValue(fieldValue);
} else {
return false;
}
}
if (fieldValue == null) {
return this instanceof NameIsNull;
}
}
}
if (function != null) {
fieldValue = function.apply(fieldValue);
}
return apply(fieldValue);
}
ObjectWriter objectWriter = writerContext.getObjectWriter(object.getClass());
if (objectWriter instanceof ObjectWriterAdapter) {
FieldWriter fieldWriter = objectWriter.getFieldWriter(fieldNameNameHash);
Object fieldValue = fieldWriter.getFieldValue(object);
if (fieldValue == null) {
return false;
}
if (fieldName2 != null) {
for (int i = 0; i < fieldName2.length; i++) {
String name = fieldName2[i];
if (fieldValue instanceof Map) {
fieldValue = ((Map) fieldValue).get(name);
} else {
ObjectWriter objectWriter2 = writerContext.getObjectWriter(fieldValue.getClass());
if (objectWriter2 instanceof ObjectWriterAdapter) {
FieldWriter fieldWriter2 = objectWriter2.getFieldWriter(fieldNameNameHash2[i]);
if (fieldWriter2 == null) {
return false;
}
fieldValue = fieldWriter2.getFieldValue(fieldValue);
} else {
return false;
}
}
if (fieldValue == null) {
return false;
}
}
}
if (function != null) {
fieldValue = function.apply(fieldValue);
}
return apply(fieldValue);
}
if (function != null) {
Object fieldValue = function.apply(object);
return apply(fieldValue);
}
if (fieldName == null) {
return apply(object);
}
return false;
}
protected void excludeArray() {
this.includeArray = false;
}
}
static final class NameStringOpSegment
extends NameFilter {
final Operator operator;
final String value;
public NameStringOpSegment(
String fieldName,
long fieldNameNameHash,
String[] fieldName2,
long[] fieldNameNameHash2,
Function expr,
Operator operator,
String value
) {
super(fieldName, fieldNameNameHash, fieldName2, fieldNameNameHash2, expr);
this.operator = operator;
this.value = value;
}
protected boolean applyNull() {
return operator == Operator.NE;
}
@Override
public boolean apply(Object fieldValue) {
if (!(fieldValue instanceof String)) {
return false;
}
int cmp = ((String) fieldValue).compareTo(this.value);
switch (operator) {
case LT:
return cmp < 0;
case LE:
return cmp <= 0;
case EQ:
return cmp == 0;
case NE:
return cmp != 0;
case GT:
return cmp > 0;
case GE:
return cmp >= 0;
default:
throw new UnsupportedOperationException();
}
}
}
static final class NameArrayOpSegment
extends NameFilter {
final Operator operator;
final JSONArray array;
public NameArrayOpSegment(
String fieldName,
long fieldNameNameHash,
String[] fieldName2,
long[] fieldNameNameHash2,
Function function,
Operator operator,
JSONArray array
) {
super(fieldName, fieldNameNameHash, fieldName2, fieldNameNameHash2, function);
this.operator = operator;
this.array = array;
}
@Override
boolean apply(Object fieldValue) {
if (Objects.requireNonNull(operator) == Operator.EQ) {
return array.equals(fieldValue);
}
throw new JSONException("not support operator : " + operator);
}
}
static final class NameObjectOpSegment
extends NameFilter {
final Operator operator;
final JSONObject object;
public NameObjectOpSegment(
String fieldName,
long fieldNameNameHash,
String[] fieldName2,
long[] fieldNameNameHash2,
Function function,
Operator operator,
JSONObject object) {
super(fieldName, fieldNameNameHash, fieldName2, fieldNameNameHash2, function);
this.operator = operator;
this.object = object;
}
@Override
boolean apply(Object fieldValue) {
if (Objects.requireNonNull(operator) == Operator.EQ) {
return object.equals(fieldValue);
}
throw new JSONException("not support operator : " + operator);
}
}
static final class NameStringInSegment
extends NameFilter {
private final String[] values;
private final boolean not;
public NameStringInSegment(String fieldName, long fieldNameNameHash, String[] values, boolean not) {
super(fieldName, fieldNameNameHash);
this.values = values;
this.not = not;
}
protected boolean applyNull() {
return not;
}
@Override
public boolean apply(Object fieldValue) {
for (String value : values) {
if (value == fieldValue) {
return !not;
} else if (value != null && value.equals(fieldValue)) {
return !not;
}
}
return not;
}
}
static final class NameStringContainsSegment
extends NameFilter {
private final String[] values;
private final boolean not;
public NameStringContainsSegment(
String fieldName,
long fieldNameNameHash,
String[] fieldName2,
long[] fieldNameNameHash2,
String[] values, boolean not) {
super(fieldName, fieldNameNameHash, fieldName2, fieldNameNameHash2, null);
this.values = values;
this.not = not;
}
@Override
public boolean apply(Object fieldValue) {
if (fieldValue instanceof Collection) {
Collection collection = (Collection) fieldValue;
boolean containsAll = true;
for (String value : values) {
if (!collection.contains(value)) {
containsAll = false;
break;
}
}
if (containsAll) {
return !not;
}
}
return not;
}
}
static final class NameMatchFilter
extends NameFilter {
final String startsWithValue;
final String endsWithValue;
final String[] containsValues;
final int minLength;
final boolean not;
public NameMatchFilter(
String fieldName,
long fieldNameNameHash,
String startsWithValue,
String endsWithValue,
String[] containsValues,
boolean not) {
super(fieldName, fieldNameNameHash);
this.startsWithValue = startsWithValue;
this.endsWithValue = endsWithValue;
this.containsValues = containsValues;
this.not = not;
int len = 0;
if (startsWithValue != null) {
len += startsWithValue.length();
}
if (endsWithValue != null) {
len += endsWithValue.length();
}
if (containsValues != null) {
for (String item : containsValues) {
len += item.length();
}
}
this.minLength = len;
}
@Override
boolean apply(Object arg) {
if (!(arg instanceof String)) {
return false;
}
String fieldValue = (String) arg;
if (fieldValue.length() < minLength) {
return not;
}
int start = 0;
if (startsWithValue != null) {
if (!fieldValue.startsWith(startsWithValue)) {
return not;
}
start += startsWithValue.length();
}
if (containsValues != null) {
for (String containsValue : containsValues) {
int index = fieldValue.indexOf(containsValue, start);
if (index == -1) {
return not;
}
start = index + containsValue.length();
}
}
if (endsWithValue != null) {
if (!fieldValue.endsWith(endsWithValue)) {
return not;
}
}
return !not;
}
}
static final class NameExistsFilter
extends JSONPathFilter {
final String name;
final long nameHashCode;
public NameExistsFilter(String name, long nameHashCode) {
this.name = name;
this.nameHashCode = nameHashCode;
}
@Override
public void eval(JSONPath.Context context) {
Object object = context.parent == null
? context.root
: context.parent.value;
JSONArray array = new JSONArray();
if (object instanceof List) {
List list = (List) object;
for (int i = 0; i < list.size(); i++) {
Object item = list.get(i);
if (item instanceof Map) {
if (((Map) item).containsKey(name)) {
array.add(item);
}
}
}
context.value = array;
return;
}
if (object instanceof Map) {
Map map = (Map) object;
Object value = map.get(name);
context.value = value != null ? object : null;
return;
}
if (object instanceof JSONPath.Sequence) {
List list = ((JSONPath.Sequence) object).values;
for (int i = 0; i < list.size(); i++) {
Object item = list.get(i);
if (item instanceof Map) {
if (((Map) item).containsKey(name)) {
array.add(item);
}
}
}
if (context.next != null) {
context.value = new JSONPath.Sequence(array);
} else {
context.value = array;
}
return;
}
throw new UnsupportedOperationException();
}
@Override
public void accept(JSONReader jsonReader, JSONPath.Context context) {
eval(context);
}
@Override
public String toString() {
return '?' + name;
}
@Override
public boolean apply(JSONPath.Context context, Object object) {
throw new UnsupportedOperationException();
}
}
static final class NameIntBetweenSegment
extends NameFilter {
private final long begin;
private final long end;
private final boolean not;
public NameIntBetweenSegment(String fieldName, long fieldNameNameHash, long begin, long end, boolean not) {
super(fieldName, fieldNameNameHash);
this.begin = begin;
this.end = end;
this.not = not;
}
protected boolean applyNull() {
return not;
}
@Override
public boolean apply(Object fieldValue) {
if (fieldValue instanceof Byte
|| fieldValue instanceof Short
|| fieldValue instanceof Integer
|| fieldValue instanceof Long
) {
long fieldValueLong = ((Number) fieldValue).longValue();
if (fieldValueLong >= begin && fieldValueLong <= end) {
return !not;
}
return not;
}
if (fieldValue instanceof Float
|| fieldValue instanceof Double
) {
double fieldValueDouble = ((Number) fieldValue).doubleValue();
if (fieldValueDouble >= begin && fieldValueDouble <= end) {
return !not;
}
return not;
}
if (fieldValue instanceof BigDecimal) {
BigDecimal decimal = (BigDecimal) fieldValue;
int cmpBegin = decimal.compareTo(BigDecimal.valueOf(begin));
int cmpEnd = decimal.compareTo(BigDecimal.valueOf(end));
if (cmpBegin >= 0 && cmpEnd <= 0) {
return !not;
}
return not;
}
if (fieldValue instanceof BigInteger) {
BigInteger bigInt = (BigInteger) fieldValue;
int cmpBegin = bigInt.compareTo(BigInteger.valueOf(begin));
int cmpEnd = bigInt.compareTo(BigInteger.valueOf(end));
if (cmpBegin >= 0 && cmpEnd <= 0) {
return !not;
}
return not;
}
return not;
}
}
static final class NameLongContainsSegment
extends NameFilter {
private final long[] values;
private final boolean not;
public NameLongContainsSegment(
String fieldName,
long fieldNameNameHash,
String[] fieldName2,
long[] fieldNameNameHash2,
long[] values, boolean not) {
super(fieldName, fieldNameNameHash, fieldName2, fieldNameNameHash2, null);
this.values = values;
this.not = not;
}
@Override
public boolean apply(Object fieldValue) {
if (fieldValue instanceof Collection) {
Collection collection = (Collection) fieldValue;
boolean containsAll = true;
for (long value : values) {
boolean containsItem = false;
for (Object item : collection) {
long longItem;
if (item instanceof Byte
|| item instanceof Short
|| item instanceof Integer
|| item instanceof Long) {
longItem = ((Number) item).longValue();
if (longItem == value) {
containsItem = true;
break;
}
}
if (item instanceof Float) {
if (value == (Float) item) {
containsItem = true;
break;
}
}
if (item instanceof Double) {
if (value == (Double) item) {
containsItem = true;
break;
}
}
if (item instanceof BigDecimal) {
BigDecimal decimal = (BigDecimal) item;
long longValue = decimal.longValue();
if (value == longValue && decimal.compareTo(BigDecimal.valueOf(value)) == 0) {
containsItem = true;
break;
}
}
if (item instanceof BigInteger) {
BigInteger bigiInt = (BigInteger) item;
long longValue = bigiInt.longValue();
if (value == longValue && bigiInt.equals(BigInteger.valueOf(value))) {
containsItem = true;
break;
}
}
}
if (!containsItem) {
containsAll = false;
break;
}
}
if (containsAll) {
return !not;
}
}
return not;
}
}
static final class NameIntInSegment
extends NameFilter {
private final long[] values;
private final boolean not;
public NameIntInSegment(
String fieldName,
long fieldNameNameHash,
String[] fieldName2,
long[] fieldNameNameHash2,
Function expr,
long[] values,
boolean not) {
super(fieldName, fieldNameNameHash, fieldName2, fieldNameNameHash2, expr);
this.values = values;
this.not = not;
}
protected boolean applyNull() {
return not;
}
@Override
public boolean apply(Object fieldValue) {
if (fieldValue instanceof Byte
|| fieldValue instanceof Short
|| fieldValue instanceof Integer
|| fieldValue instanceof Long
) {
long fieldValueLong = ((Number) fieldValue).longValue();
for (long value : values) {
if (value == fieldValueLong) {
return !not;
}
}
return not;
}
if (fieldValue instanceof Float
|| fieldValue instanceof Double
) {
double fieldValueDouble = ((Number) fieldValue).doubleValue();
for (long value : values) {
if (value == fieldValueDouble) {
return !not;
}
}
return not;
}
if (fieldValue instanceof BigDecimal) {
BigDecimal decimal = (BigDecimal) fieldValue;
long longValue = decimal.longValue();
for (long value : values) {
if (value == longValue && decimal.compareTo(BigDecimal.valueOf(value)) == 0) {
return !not;
}
}
return not;
}
if (fieldValue instanceof BigInteger) {
BigInteger bigiInt = (BigInteger) fieldValue;
long longValue = bigiInt.longValue();
for (long value : values) {
if (value == longValue && bigiInt.equals(BigInteger.valueOf(value))) {
return !not;
}
}
return not;
}
return not;
}
}
}