package foundation.dao;
|
|
import java.util.Date;
|
import java.util.HashSet;
|
import java.util.Iterator;
|
import java.util.Set;
|
|
import org.json.JSONArray;
|
|
import foundation.data.meta.field.Field;
|
import foundation.data.meta.field.FieldsRuntime;
|
import foundation.json.JArrayReader;
|
import foundation.json.JSONReader;
|
import foundation.json.JType;
|
import foundation.server.config.DBaseType;
|
import foundation.translator.ITranslator;
|
import foundation.translator.Translator;
|
import foundation.translator.ValueType;
|
import foundation.util.ContentBuilder;
|
import foundation.util.ID;
|
import foundation.util.MapList;
|
import foundation.util.Util;
|
import foundation.variant.provider.DataEvent;
|
import foundation.variant.provider.IVariantsConsumer;
|
import foundation.variant.provider.IVariantsProvider;
|
import foundation.variant.provider.VariantLink;
|
import foundation.variant.provider.VariantProviderType;
|
|
public class Filter implements IVariantsConsumer, IVariantsProvider, Iterable<FilterItem> {
|
|
public static final Filter All = new Filter();
|
public static String ProviderName = "filter";
|
private DBaseType dbaseType;
|
private Set<String> VariantNames;
|
private FieldsRuntime entityMeta;
|
private MapList<String, FilterItem> items;
|
private String rawFilter;
|
private boolean raw = false;
|
private boolean empty;
|
private Set<Object> marks;
|
|
|
public Filter() {
|
this(DBaseType.getMain());
|
}
|
|
public Filter(DBaseType dbaseType) {
|
this.dbaseType = dbaseType;
|
items = new MapList<String, FilterItem>();
|
VariantNames = new HashSet<String>();
|
VariantNames.add("filter");
|
}
|
|
public Filter(String filter) {
|
this(DBaseType.getMain(), filter);
|
}
|
|
public Filter(DBaseType dbaseType, String filter) {
|
this.dbaseType = dbaseType;
|
items = new MapList<String, FilterItem>();
|
VariantNames = new HashSet<String>();
|
VariantNames.add("filter");
|
rawFilter = filter;
|
raw = true;
|
}
|
|
public Filter(String fieldName, String value) {
|
this();
|
add(fieldName, "=", Util.quotedStr(value));
|
}
|
|
public Filter(DBaseType dbaseType, String fieldName, String value) {
|
this(dbaseType);
|
add(fieldName, "=", Util.quotedStr(value));
|
}
|
|
public Filter(String fieldName, int value) {
|
this();
|
add(fieldName, "=", String.valueOf(value));
|
}
|
|
public Filter(DBaseType dbaseType, String fieldName, int value) {
|
this(dbaseType);
|
add(fieldName, "=", String.valueOf(value));
|
}
|
|
public Filter(String fieldName, Date date) throws Exception {
|
this(DBaseType.getMain(), fieldName, date);
|
}
|
|
public Filter(DBaseType dbaseType, String fieldName, Date date) throws Exception {
|
this(dbaseType);
|
add(fieldName, "=", Translator.toSqlString(dbaseType, date));
|
}
|
|
public Filter(String fieldName, String operator, String value) {
|
this();
|
add(fieldName, operator, value);
|
}
|
|
public Filter(DBaseType dbaseType, String fieldName, String operator, String value) throws Exception {
|
this(dbaseType);
|
add(fieldName, operator, value);
|
}
|
|
public Filter addAll(FieldsRuntime entityMeta, Set<String> excludeNames, IVariantsProvider...valueProviders) throws Exception {
|
this.entityMeta = entityMeta;
|
|
for (int i = 0; i < valueProviders.length; i++) {
|
IVariantsProvider provider = valueProviders[i];
|
VariantLink.moveOnConsumer(null, provider, this, excludeNames);
|
}
|
|
return this;
|
}
|
|
public Filter addAll(Filter other) {
|
if (other == null) {
|
return this;
|
}
|
|
for (FilterItem item: other) {
|
items.add(item.getFieldName(), item);
|
}
|
|
if (other.isRaw()) {
|
this.rawFilter = other.rawFilter;
|
this.raw = other.raw;
|
}
|
|
return this;
|
}
|
|
public Filter add(DataReader dataReader) {
|
Object filterObject = dataReader.getValue("filter");
|
if (filterObject instanceof String) {
|
this.add(String.valueOf(filterObject));
|
return this;
|
}
|
|
if (filterObject instanceof JSONArray) {
|
JArrayReader jsonArray = dataReader.getReader("filter", JType.Array);
|
|
for (JSONReader jsonObject: jsonArray) {
|
this.add(jsonObject.getString("field"), jsonObject.getString("operator"), Util.quotedStr(jsonObject.getString("value")));
|
}
|
return this;
|
}
|
|
return this;
|
}
|
|
public Filter add(String segment) {
|
if (Util.isEmpty(segment)) {
|
return this;
|
}
|
|
FilterItem item = new FilterItem(segment);
|
items.add(ID.newValue(), item);
|
|
return this;
|
}
|
|
public Filter add(String fieldName, String value) {
|
if (value == null) {
|
this.add(fieldName, "is", "null");
|
return this;
|
}
|
|
this.add(fieldName, "=", Util.quotedStr(value));
|
return this;
|
}
|
|
public Filter add(String fieldName, Object value) {
|
if (value == null) {
|
this.add(fieldName, "is", "null");
|
return this;
|
}
|
|
this.add(fieldName, "=", String.valueOf(value));
|
return this;
|
}
|
|
public Filter add(String fieldName, String operator, String value) {
|
if (Util.isEmpty(fieldName)) {
|
return this;
|
}
|
|
if (Util.isEmpty(operator)) {
|
operator = "=";
|
}
|
|
operator = operator.trim().toLowerCase();
|
|
if ("like".equals(operator)) {
|
if (value.indexOf("%") < 0) {
|
value = "%" + value + "%";
|
}
|
}
|
else if ("in".equals(operator)) {
|
if (value.startsWith("'")) {
|
value = value.substring(1);
|
}
|
if (value.endsWith("'")) {
|
value = value.substring(0, value.length() - 1);
|
}
|
}
|
|
|
FilterItem item = new FilterItem(fieldName, operator, value);
|
items.add(fieldName, item);
|
|
VariantNames.add(fieldName.toLowerCase());
|
|
return this;
|
}
|
|
@Override
|
public void setVariant(DataEvent dataEvent, String name, Object value) throws Exception {
|
if (value == null) {
|
return;
|
}
|
|
if (entityMeta == null) {
|
throw new Exception("filter entityMeta is null");
|
}
|
|
if(!entityMeta.contains(name)) {
|
return;
|
}
|
Field field = entityMeta.get(name);
|
|
if (field == null) {
|
return;
|
}
|
|
ITranslator translator = field.getValueTranslator();
|
ValueType type = field.getType();
|
|
if (ValueType.String == type) {
|
String stringValue = value.toString();
|
String segmentValue = null;
|
|
//1. like
|
if (stringValue.startsWith("(like)")) {
|
if (stringValue.endsWith("(like)")) {
|
//1.1 all like
|
segmentValue = "'%" + stringValue.substring(7, stringValue.length() - 6) + "%'";
|
add(name, "like", segmentValue);
|
}
|
else {
|
//1.2 left like
|
segmentValue = "'%" + stringValue.substring(7) + "'";
|
add(name, "like", segmentValue);
|
}
|
}
|
else if (stringValue.endsWith("(like)")) {
|
//1.3 right like
|
segmentValue = "'" + stringValue.substring(0, stringValue.length() - 6) + "%'";
|
add(name, "like", segmentValue);
|
}
|
else {
|
//1.3 no like
|
segmentValue = "'" + stringValue + "'";
|
add(name, "=", segmentValue);
|
}
|
}
|
else {
|
String segmentValue = translator.toSqlString(dbaseType, value);
|
add(name, "=", segmentValue);
|
}
|
}
|
|
@Override
|
public void setVariants(DataEvent dataEvent, IVariantsProvider... providers) throws Exception {
|
if (providers == null || providers.length == 0) {
|
return;
|
}
|
|
Set<String> keySet = items.keySet();
|
|
for (String key: keySet) {
|
for (IVariantsProvider provider: providers) {
|
if (provider.containsVariant(key)) {
|
FilterItem item = items.get(key);
|
Object value = provider.getVariantValue(dataEvent, key);
|
|
if (!Util.isEmpty(value)) {
|
item.setValue(String.valueOf(value));
|
}
|
}
|
}
|
}
|
}
|
|
@Override
|
public boolean isVariantNull(String name) {
|
return empty;
|
}
|
|
public FilterItem getItemByName(String name) {
|
if (items == null) {
|
return null;
|
}
|
return items.get(name);
|
}
|
|
public FilterItem removeItemByName(String name) {
|
if (items == null) {
|
return null;
|
}
|
return items.remove(name);
|
}
|
|
public boolean isRaw() {
|
return raw;
|
}
|
|
public String getRawFilter() {
|
return rawFilter;
|
}
|
|
public boolean isEmpty() {
|
return items.isEmpty() && Util.isEmpty(rawFilter);
|
}
|
|
public boolean containsSlaveTables(String... tableNames) {
|
String sql = toString();
|
|
if (Util.isEmpty(sql) || tableNames == null || tableNames.length == 0) {
|
return false;
|
}
|
|
sql = sql.toLowerCase();
|
int max = tableNames.length;
|
|
for (int i = 0; i < max; i++) {
|
String tableName = tableNames[i];
|
|
if (Util.isEmpty(tableName)) {
|
continue;
|
}
|
|
tableName = tableName.toLowerCase() + ".";
|
|
if (sql.indexOf(tableName) >= 0) {
|
return true;
|
}
|
}
|
|
return false;
|
}
|
|
public synchronized void addMark(Object mark) {
|
if (marks == null) {
|
marks = new HashSet<Object>();
|
}
|
|
marks.add(mark);
|
}
|
|
public boolean containsMark(Object mark) {
|
if (marks == null || mark == null) {
|
return false;
|
}
|
|
return marks.contains(mark);
|
}
|
|
@Override
|
public String toString() {
|
if (raw) {
|
return rawFilter;
|
}
|
|
if (items.isEmpty()) {
|
return "1=1";
|
}
|
|
ContentBuilder result = new ContentBuilder(" and ");
|
Set<String> keySet = items.keySet();
|
for (String key : keySet) {
|
FilterItem filterItem = items.get(key);
|
result.append(filterItem.toSQLString());
|
}
|
|
if (result.isEmpty()) {
|
result.append(" 1 = 1 ");
|
}
|
|
return "(" + result + ")";
|
}
|
|
@Override
|
public String getProviderName() {
|
return ProviderName;
|
}
|
|
@Override
|
public VariantProviderType getProviderType() {
|
return VariantProviderType.Transiant;
|
}
|
|
@Override
|
public boolean containsVariant(String name) {
|
if (name == null) {
|
return false;
|
}
|
|
return VariantNames.contains(name);
|
}
|
|
@Override
|
public Object getVariantValue(DataEvent dataEvent, String name) {
|
if ("filter".equalsIgnoreCase(name)) {
|
return toString();
|
}
|
|
FilterItem item = items.get(name);
|
|
if (item == null) {
|
return null;
|
}
|
|
return item.getValue();
|
}
|
|
@Override
|
public Set<String> getVariantNames() {
|
return VariantNames;
|
}
|
|
@Override
|
public Iterator<FilterItem> iterator() {
|
return items.iterator();
|
}
|
}
|