新版FilterNodeBean

This commit is contained in:
kamhung
2015-12-04 21:00:22 +08:00
parent 32a837444a
commit 5c0f97d62b
3 changed files with 151 additions and 53 deletions

View File

@@ -8,6 +8,7 @@ package com.wentch.redkale.source;
import com.wentch.redkale.util.*;
import java.io.*;
import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.function.*;
/**
@@ -39,75 +40,149 @@ public class FilterJoinNode extends FilterNode {
this.value = value;
}
public static FilterNode create(Class joinClass, String joinColumn, String column, Serializable value) {
protected FilterJoinNode(FilterJoinNode node) {
this(node.joinClass, node.joinColumns, node.column, node.express, node.value);
this.joinEntity = node.joinEntity;
this.or = node.or;
this.nodes = node.nodes;
}
public static FilterJoinNode create(Class joinClass, String joinColumn, String column, Serializable value) {
return new FilterJoinNode(joinClass, new String[]{joinColumn}, column, value);
}
public static FilterNode create(Class joinClass, String joinColumn, String column, FilterExpress express, Serializable value) {
public static FilterJoinNode create(Class joinClass, String joinColumn, String column, FilterExpress express, Serializable value) {
return new FilterJoinNode(joinClass, new String[]{joinColumn}, column, express, value);
}
public static FilterNode create(Class joinClass, String[] joinColumns, String column, Serializable value) {
public static FilterJoinNode create(Class joinClass, String[] joinColumns, String column, Serializable value) {
return new FilterJoinNode(joinClass, joinColumns, column, value);
}
public static FilterNode create(Class joinClass, String[] joinColumns, String column, FilterExpress express, Serializable value) {
public static FilterJoinNode create(Class joinClass, String[] joinColumns, String column, FilterExpress express, Serializable value) {
return new FilterJoinNode(joinClass, joinColumns, column, express, value);
}
@Override
protected void check(FilterNode node) {
Objects.requireNonNull(node);
if (!(node instanceof FilterJoinNode)) throw new IllegalArgumentException(this + " check " + String.valueOf(node) + "is not a " + FilterJoinNode.class.getSimpleName());
protected FilterNode any(final FilterNode node0, boolean signor) {
Objects.requireNonNull(node0);
if (!(node0 instanceof FilterJoinNode)) {
throw new IllegalArgumentException(this + (signor ? " or " : " and ") + " a node but " + String.valueOf(node0) + "is not a " + FilterJoinNode.class.getSimpleName());
}
final FilterJoinNode node = (FilterJoinNode) node0;
if (this.nodes == null) {
this.nodes = new FilterNode[]{node};
this.or = signor;
return this;
}
if (or == signor || this.column == null) {
FilterNode[] newsiblings = new FilterNode[nodes.length + 1];
System.arraycopy(nodes, 0, newsiblings, 0, nodes.length);
newsiblings[nodes.length] = node;
this.nodes = newsiblings;
if (this.column == null) this.or = signor;
return this;
}
this.nodes = new FilterNode[]{new FilterJoinNode(node), node};
this.column = null;
this.express = null;
this.value = null;
this.joinClass = null;
this.joinEntity = null;
this.joinColumns = null;
this.or = signor;
return this;
}
@Override
protected <T> CharSequence createSQLExpress(final EntityInfo<T> info, final Map<Class, String> joinTabalis) {
return super.createSQLExpress(this.joinEntity, joinTabalis);
return super.createSQLExpress(this.joinEntity == null ? info : this.joinEntity, joinTabalis);
}
@Override
protected <T, E> Predicate<T> createPredicate(final EntityCache<T> cache) {
if (column == null && this.nodes == null) return null;
final EntityCache<E> joinCache = this.joinEntity.getCache();
Predicate<E> filter = createChildPredicate();
if (filter == null) return null;
final AtomicBoolean more = new AtomicBoolean();
Predicate<E> filter = createJoinPredicate(more);
Predicate<T> rs = null;
if (filter == null && !more.get()) return rs;
if (filter != null) {
final Predicate<E> inner = filter;
rs = new Predicate<T>() {
final Predicate<E> inner = filter;
return new Predicate<T>() {
@Override
public boolean test(final T t) {
Predicate<E> joinPredicate = null;
for (String joinColumn : joinColumns) {
final Serializable key = cache.getAttribute(joinColumn).get(t);
final Attribute<E, Serializable> joinAttr = joinCache.getAttribute(joinColumn);
Predicate<E> p = (E e) -> key.equals(joinAttr.get(e));
joinPredicate = joinPredicate == null ? p : joinPredicate.and(p);
@Override
public boolean test(final T t) {
Predicate<E> joinPredicate = null;
for (String joinColumn : joinColumns) {
final Serializable key = cache.getAttribute(joinColumn).get(t);
final Attribute<E, Serializable> joinAttr = joinCache.getAttribute(joinColumn);
Predicate<E> p = (E e) -> key.equals(joinAttr.get(e));
joinPredicate = joinPredicate == null ? p : joinPredicate.and(p);
}
return joinCache.exists(inner.and(joinPredicate));
}
return joinCache.exists(inner.and(joinPredicate));
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(" #-- ON ").append(joinColumns[0]).append("=").append(joinClass == null ? "null" : joinClass.getSimpleName()).append(".").append(joinColumns[0]);
for (int i = 1; i < joinColumns.length; i++) {
sb.append(" AND ").append(joinColumns[i]).append("=").append(joinClass == null ? "null" : joinClass.getSimpleName()).append(".").append(joinColumns[i]);
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(" #-- ON ").append(joinColumns[0]).append("=").append(joinClass == null ? "null" : joinClass.getSimpleName()).append(".").append(joinColumns[0]);
for (int i = 1; i < joinColumns.length; i++) {
sb.append(" AND ").append(joinColumns[i]).append("=").append(joinClass == null ? "null" : joinClass.getSimpleName()).append(".").append(joinColumns[i]);
}
sb.append(" --# ").append(inner.toString());
return sb.toString();
}
};
}
if (more.get()) { //存在不同Class的关联表
if (this.nodes != null) {
for (FilterNode node : this.nodes) {
if (((FilterJoinNode) node).joinClass == this.joinClass) continue;
Predicate<T> f = node.createPredicate(cache);
if (f == null) continue;
final Predicate<T> one = rs;
final Predicate<T> two = f;
rs = (rs == null) ? f : (or ? new Predicate<T>() {
@Override
public boolean test(T t) {
return one.test(t) || two.test(t);
}
@Override
public String toString() {
return "(" + one + " OR " + two + ")";
}
} : new Predicate<T>() {
@Override
public boolean test(T t) {
return one.test(t) && two.test(t);
}
@Override
public String toString() {
return "(" + one + " AND " + two + ")";
}
});
}
sb.append(" --# ").append(inner.toString());
return sb.toString();
}
};
}
return rs;
}
private <E> Predicate<E> createChildPredicate() {
private <E> Predicate<E> createJoinPredicate(final AtomicBoolean more) {
if (column == null && this.nodes == null) return null;
final EntityCache<E> joinCache = this.joinEntity.getCache();
Predicate<E> filter = createElementPredicate(joinCache, true);
if (this.nodes != null) {
for (FilterNode node : this.nodes) {
Predicate<E> f = ((FilterJoinNode) node).createChildPredicate();
if (((FilterJoinNode) node).joinClass != this.joinClass) {
more.set(true);
continue;
}
Predicate<E> f = ((FilterJoinNode) node).createJoinPredicate(more);
if (f == null) continue;
final Predicate<E> one = filter;
final Predicate<E> two = f;
@@ -141,21 +216,52 @@ public class FilterJoinNode extends FilterNode {
@Override
protected <T> CharSequence createSQLJoin(final Function<Class, EntityInfo> func, final Map<Class, String> joinTabalis, final EntityInfo<T> info) {
boolean morejoin = false;
if (this.joinEntity == null) {
this.joinEntity = func.apply(this.joinClass);
if (this.joinClass != null) this.joinEntity = func.apply(this.joinClass);
if (this.nodes != null) {
for (FilterNode node : this.nodes) {
if (node instanceof FilterJoinNode) {
((FilterJoinNode) node).joinEntity = func.apply(((FilterJoinNode) node).joinClass);
FilterJoinNode joinNode = ((FilterJoinNode) node);
if (joinNode.joinClass != null) {
joinNode.joinEntity = func.apply(joinNode.joinClass);
if (this.joinClass != null && this.joinClass != joinNode.joinClass) morejoin = true;
}
}
}
}
}
StringBuilder sb = new StringBuilder();
sb.append(" INNER JOIN ").append(joinEntity.getTable()).append(" ").append(joinTabalis.get(this.joinClass))
.append(" ON ").append(info.getSQLColumn("a", joinColumns[0])).append(" = ").append(this.joinEntity.getSQLColumn(joinTabalis.get(this.joinClass), joinColumns[0]));
if (this.joinClass != null) {
sb.append(createElementSQLJoin(joinTabalis, info, this));
}
if (morejoin) {
Set<Class> set = new HashSet<>();
if (this.joinClass != null) set.add(this.joinClass);
for (FilterNode node : this.nodes) {
if (node instanceof FilterJoinNode) {
FilterJoinNode joinNode = ((FilterJoinNode) node);
if (!set.contains(joinNode.joinClass)) {
CharSequence cs = createElementSQLJoin(joinTabalis, info, joinNode);
if (cs != null) {
sb.append(cs);
set.add(joinNode.joinClass);
}
}
}
}
}
return sb;
}
private static CharSequence createElementSQLJoin(final Map<Class, String> joinTabalis, final EntityInfo info, final FilterJoinNode node) {
if (node.joinClass == null) return null;
StringBuilder sb = new StringBuilder();
String[] joinColumns = node.joinColumns;
sb.append(" INNER JOIN ").append(node.joinEntity.getTable()).append(" ").append(joinTabalis.get(node.joinClass))
.append(" ON ").append(info.getSQLColumn("a", joinColumns[0])).append(" = ").append(node.joinEntity.getSQLColumn(joinTabalis.get(node.joinClass), joinColumns[0]));
for (int i = 1; i < joinColumns.length; i++) {
sb.append(" AND ").append(info.getSQLColumn("a", joinColumns[i])).append(" = ").append(this.joinEntity.getSQLColumn(joinTabalis.get(this.joinClass), joinColumns[i]));
sb.append(" AND ").append(info.getSQLColumn("a", joinColumns[i])).append(" = ").append(node.joinEntity.getSQLColumn(joinTabalis.get(node.joinClass), joinColumns[i]));
}
return sb;
}
@@ -173,7 +279,7 @@ public class FilterJoinNode extends FilterNode {
@Override
protected void putJoinTabalis(Map<Class, String> map) {
if (!map.containsKey(this.joinClass)) map.put(joinClass, String.valueOf((char) ('b' + map.size())));
if (this.joinClass != null && !map.containsKey(this.joinClass)) map.put(joinClass, String.valueOf((char) ('b' + map.size())));
if (this.nodes == null) return;
for (FilterNode node : this.nodes) {
node.putJoinTabalis(map);

View File

@@ -77,7 +77,7 @@ public class FilterNode {
return or(new FilterNode(column, express, value));
}
protected final FilterNode any(FilterNode node, boolean signor) {
protected FilterNode any(FilterNode node, boolean signor) {
Objects.requireNonNull(node);
if (this.column == null) {
this.column = node.column;
@@ -97,7 +97,7 @@ public class FilterNode {
this.nodes = newsiblings;
return this;
}
FilterNode newnode = new FilterNode(this.column, this.express, this.value);
FilterNode newnode = new FilterNode(this.column, this.express, this.value);
newnode.or = this.or;
newnode.nodes = this.nodes;
this.nodes = new FilterNode[]{newnode, node};
@@ -108,15 +108,6 @@ public class FilterNode {
return this;
}
/**
* 该方法需要重载
*
* @param node
*/
protected void check(FilterNode node) {
Objects.requireNonNull(node);
}
/**
* 该方法需要重载
*
@@ -185,11 +176,10 @@ public class FilterNode {
* @param <T>
* @param joinTabalis
* @param info
* @param bean
* @return
*/
protected <T> CharSequence createSQLExpress(final EntityInfo<T> info, final Map<Class, String> joinTabalis) {
CharSequence sb0 = createElementSQLExpress(info, joinTabalis == null ? null : joinTabalis.get(info.getType()));
CharSequence sb0 = this.column == null || info == null ? null : createElementSQLExpress(info, joinTabalis == null ? null : joinTabalis.get(info.getType()));
if (this.nodes == null) return sb0;
final StringBuilder rs = new StringBuilder();
rs.append('(');

View File

@@ -194,6 +194,8 @@ public final class FilterNodeBean<T> implements Comparable<FilterNodeBean<T>> {
FilterNodeBean node = nodemap.get(key);
if (node == null) {
nodemap.put(key, nodeBean);
} else if (nodeBean.joinClass == null && node.joinClass != null) { //非joinNode 关联 joinNode
nodemap.put(key, nodeBean.any(node, key.substring(key.lastIndexOf('.') + 1).contains("[OR]")));
} else {
node.any(nodeBean, key.substring(key.lastIndexOf('.') + 1).contains("[OR]"));
}