This commit is contained in:
@@ -142,8 +142,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number getNumberResult(Class entityClass, Reckon reckon, String column, FilterBean bean) {
|
||||
return source.getNumberResult(entityClass, reckon, column, bean);
|
||||
public final Number getNumberResult(Class entityClass, Reckon reckon, String column, FilterBean bean) {
|
||||
return getNumberResult(entityClass, reckon, column, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,8 +157,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K extends Serializable, V extends Number> Map<K, V> getMapResult(Class entityClass, String keyColumn, Reckon reckon, String reckonColumn, FilterBean bean) {
|
||||
return source.getMapResult(entityClass, keyColumn, reckon, reckonColumn, bean);
|
||||
public final <K extends Serializable, V extends Number> Map<K, V> getMapResult(Class entityClass, String keyColumn, Reckon reckon, String reckonColumn, FilterBean bean) {
|
||||
return getMapResult(entityClass, keyColumn, reckon, reckonColumn, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -187,8 +187,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T find(Class<T> clazz, FilterBean bean) {
|
||||
return source.find(clazz, bean);
|
||||
public final <T> T find(Class<T> clazz, FilterBean bean) {
|
||||
return find(clazz, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -202,8 +202,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean exists(Class<T> clazz, FilterBean bean) {
|
||||
return source.exists(clazz, bean);
|
||||
public final <T> boolean exists(Class<T> clazz, FilterBean bean) {
|
||||
return exists(clazz, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -217,8 +217,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, V> HashSet<V> queryColumnSet(String selectedColumn, Class<T> clazz, FilterBean bean) {
|
||||
return source.queryColumnSet(selectedColumn, clazz, bean);
|
||||
public final <T, V> HashSet<V> queryColumnSet(String selectedColumn, Class<T> clazz, FilterBean bean) {
|
||||
return queryColumnSet(selectedColumn, clazz, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -232,8 +232,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, V> List<V> queryColumnList(String selectedColumn, Class<T> clazz, FilterBean bean) {
|
||||
return source.queryColumnList(selectedColumn, clazz, bean);
|
||||
public final <T, V> List<V> queryColumnList(String selectedColumn, Class<T> clazz, FilterBean bean) {
|
||||
return queryColumnList(selectedColumn, clazz, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -242,8 +242,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K extends Serializable, T> Map<K, T> queryMap(Class<T> clazz, FilterBean bean) {
|
||||
return source.queryMap(clazz, bean);
|
||||
public final <K extends Serializable, T> Map<K, T> queryMap(Class<T> clazz, FilterBean bean) {
|
||||
return queryMap(clazz, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -252,8 +252,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K extends Serializable, T> Map<K, T> queryMap(Class<T> clazz, SelectColumn selects, FilterBean bean) {
|
||||
return source.queryMap(clazz, selects, bean);
|
||||
public final <K extends Serializable, T> Map<K, T> queryMap(Class<T> clazz, SelectColumn selects, FilterBean bean) {
|
||||
return queryMap(clazz, selects, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -267,8 +267,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryList(Class<T> clazz, FilterBean bean) {
|
||||
return source.queryList(clazz, bean);
|
||||
public final <T> List<T> queryList(Class<T> clazz, FilterBean bean) {
|
||||
return queryList(clazz, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -277,8 +277,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryList(Class<T> clazz, SelectColumn selects, FilterBean bean) {
|
||||
return source.queryList(clazz, bean);
|
||||
public final <T> List<T> queryList(Class<T> clazz, SelectColumn selects, FilterBean bean) {
|
||||
return queryList(clazz, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -292,8 +292,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryList(Class<T> clazz, Flipper flipper, FilterBean bean) {
|
||||
return source.queryList(clazz, flipper, bean);
|
||||
public final <T> List<T> queryList(Class<T> clazz, Flipper flipper, FilterBean bean) {
|
||||
return queryList(clazz, flipper, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -302,13 +302,13 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryList(Class<T> clazz, SelectColumn selects, Flipper flipper, FilterBean bean) {
|
||||
return source.queryList(clazz, selects, flipper, bean);
|
||||
public final <T> List<T> queryList(Class<T> clazz, SelectColumn selects, Flipper flipper, FilterBean bean) {
|
||||
return queryList(clazz, selects, flipper, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, V> Sheet<V> queryColumnSheet(String selectedColumn, Class<T> clazz, Flipper flipper, FilterBean bean) {
|
||||
return source.queryColumnSheet(selectedColumn, clazz, flipper, bean);
|
||||
public final <T, V> Sheet<V> queryColumnSheet(String selectedColumn, Class<T> clazz, Flipper flipper, FilterBean bean) {
|
||||
return queryColumnSheet(selectedColumn, clazz, flipper, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -317,8 +317,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Sheet<T> querySheet(Class<T> clazz, Flipper flipper, FilterBean bean) {
|
||||
return source.querySheet(clazz, flipper, bean);
|
||||
public final <T> Sheet<T> querySheet(Class<T> clazz, Flipper flipper, FilterBean bean) {
|
||||
return querySheet(clazz, flipper, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -327,8 +327,8 @@ public class DataSourceService implements DataSource, Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Sheet<T> querySheet(Class<T> clazz, SelectColumn selects, Flipper flipper, FilterBean bean) {
|
||||
return source.querySheet(clazz, selects, flipper, bean);
|
||||
public final <T> Sheet<T> querySheet(Class<T> clazz, SelectColumn selects, Flipper flipper, FilterBean bean) {
|
||||
return querySheet(clazz, selects, flipper, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -110,7 +110,7 @@ public final class DataDefaultSource implements DataSource, Nameable, Function<C
|
||||
}
|
||||
}
|
||||
|
||||
private final Function<Class, List> fullloader = (t) -> querySheet(false, false, t, null, null, (FilterNode) null, null).list(true);
|
||||
private final Function<Class, List> fullloader = (t) -> querySheet(false, false, t, null, null, (FilterNode) null).list(true);
|
||||
|
||||
public DataDefaultSource() throws IOException {
|
||||
this("");
|
||||
@@ -339,10 +339,6 @@ public final class DataDefaultSource implements DataSource, Nameable, Function<C
|
||||
return EntityInfo.load(clazz, this.nodeid, this.cacheForbidden, fullloader);
|
||||
}
|
||||
|
||||
private <T extends FilterBean> FilterBeanNode loadFilterBeanNode(Class<T> clazz) {
|
||||
return FilterBeanNode.load(clazz, this.nodeid, this.cacheForbidden, fullloader);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将entity的对象全部加载到Cache中去,如果clazz没有被@javax.persistence.Cacheable注解则不做任何事
|
||||
* <p>
|
||||
@@ -651,7 +647,7 @@ public final class DataDefaultSource implements DataSource, Nameable, Function<C
|
||||
if (!info.isVirtualEntity()) {
|
||||
Map<Class, String> joinTabalis = node.getJoinTabalis();
|
||||
CharSequence join = node.createSQLJoin(this, joinTabalis, info);
|
||||
CharSequence where = node.createSQLExpress(info, joinTabalis, null);
|
||||
CharSequence where = node.createSQLExpress(info, joinTabalis);
|
||||
String sql = "DELETE " + (mysql ? "a" : "") + " FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where));
|
||||
if (debug.get()) logger.finest(info.getType().getSimpleName() + " delete sql=" + sql);
|
||||
final Statement stmt = conn.createStatement();
|
||||
@@ -1062,7 +1058,7 @@ public final class DataDefaultSource implements DataSource, Nameable, Function<C
|
||||
if (cache == null) return;
|
||||
String column = info.getPrimary().field();
|
||||
for (Serializable id : ids) {
|
||||
Sheet<T> sheet = querySheet(false, true, clazz, null, FLIPPER_ONE, FilterNode.create(column, id), null);
|
||||
Sheet<T> sheet = querySheet(false, true, clazz, null, FLIPPER_ONE, FilterNode.create(column, id));
|
||||
T value = sheet.isEmpty() ? null : sheet.list().get(0);
|
||||
if (value != null) cache.update(value);
|
||||
}
|
||||
@@ -1071,33 +1067,28 @@ public final class DataDefaultSource implements DataSource, Nameable, Function<C
|
||||
//-----------------------getNumberResult-----------------------------
|
||||
@Override
|
||||
public Number getNumberResult(final Class entityClass, final Reckon reckon, final String column) {
|
||||
return getNumberResult(entityClass, reckon, column, null, null);
|
||||
return getNumberResult(entityClass, reckon, column, (FilterNode) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number getNumberResult(final Class entityClass, final Reckon reckon, final String column, FilterBean bean) {
|
||||
return getNumberResult(entityClass, reckon, column, null, bean);
|
||||
return getNumberResult(entityClass, reckon, column, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number getNumberResult(final Class entityClass, final Reckon reckon, final String column, FilterNode node) {
|
||||
return getNumberResult(entityClass, reckon, column, node, null);
|
||||
}
|
||||
|
||||
private <T> Number getNumberResult(final Class<T> entityClass, final Reckon reckon, final String column, FilterNode node, FilterBean bean) {
|
||||
public Number getNumberResult(final Class entityClass, final Reckon reckon, final String column, final FilterNode node) {
|
||||
final Connection conn = createReadSQLConnection();
|
||||
try {
|
||||
final EntityInfo<T> info = loadEntityInfo(entityClass);
|
||||
if (node == null && bean != null) node = loadFilterBeanNode(bean.getClass());
|
||||
final EntityCache<T> cache = info.getCache();
|
||||
final EntityInfo info = loadEntityInfo(entityClass);
|
||||
final EntityCache cache = info.getCache();
|
||||
if (cache != null && (info.isVirtualEntity() || cache.isFullLoaded())) {
|
||||
if (node == null || node.isCacheUseable(this)) {
|
||||
return cache.getNumberResult(reckon, column, node, bean);
|
||||
return cache.getNumberResult(reckon, column, node);
|
||||
}
|
||||
}
|
||||
final Map<Class, String> joinTabalis = node == null ? null : node.getJoinTabalis();
|
||||
final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info);
|
||||
final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis, bean);
|
||||
final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis);
|
||||
final String sql = "SELECT " + reckon.getColumn((column == null || column.isEmpty() ? "*" : ("a." + column))) + " FROM " + info.getTable() + " a"
|
||||
+ (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where));
|
||||
if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(entityClass.getSimpleName() + " single sql=" + sql);
|
||||
@@ -1120,34 +1111,29 @@ public final class DataDefaultSource implements DataSource, Nameable, Function<C
|
||||
//-----------------------getMapResult-----------------------------
|
||||
@Override
|
||||
public <K extends Serializable, V extends Number> Map<K, V> getMapResult(Class entityClass, final String keyColumn, Reckon reckon, final String reckonColumn) {
|
||||
return getMapResult(entityClass, keyColumn, reckon, reckonColumn, null, null);
|
||||
return getMapResult(entityClass, keyColumn, reckon, reckonColumn, (FilterNode) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K extends Serializable, V extends Number> Map<K, V> getMapResult(Class entityClass, final String keyColumn, Reckon reckon, final String reckonColumn, FilterBean bean) {
|
||||
return getMapResult(entityClass, keyColumn, reckon, reckonColumn, null, bean);
|
||||
return getMapResult(entityClass, keyColumn, reckon, reckonColumn, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K extends Serializable, V extends Number> Map<K, V> getMapResult(Class entityClass, final String keyColumn, Reckon reckon, final String reckonColumn, FilterNode node) {
|
||||
return getMapResult(entityClass, keyColumn, reckon, reckonColumn, node, null);
|
||||
}
|
||||
|
||||
private <K extends Serializable, V extends Number> Map<K, V> getMapResult(final Class entityClass, final String keyColumn, final Reckon reckon, final String reckonColumn, FilterNode node, FilterBean bean) {
|
||||
public <K extends Serializable, V extends Number> Map<K, V> getMapResult(final Class entityClass, final String keyColumn, final Reckon reckon, final String reckonColumn, FilterNode node) {
|
||||
final Connection conn = createReadSQLConnection();
|
||||
try {
|
||||
final EntityInfo info = loadEntityInfo(entityClass);
|
||||
if (node == null && bean != null) node = loadFilterBeanNode(bean.getClass());
|
||||
final EntityCache cache = info.getCache();
|
||||
if (cache != null && (info.isVirtualEntity() || cache.isFullLoaded())) {
|
||||
if (node == null || node.isCacheUseable(this)) {
|
||||
return cache.getMapResult(keyColumn, reckon, reckonColumn, node, bean);
|
||||
return cache.getMapResult(keyColumn, reckon, reckonColumn, node);
|
||||
}
|
||||
}
|
||||
final String sqlkey = info.getSQLColumn(null, keyColumn);
|
||||
final Map<Class, String> joinTabalis = node == null ? null : node.getJoinTabalis();
|
||||
final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info);
|
||||
final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis, bean);
|
||||
final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis);
|
||||
final String sql = "SELECT a." + sqlkey + ", " + reckon.getColumn((reckonColumn == null || reckonColumn.isEmpty() ? "*" : ("a." + reckonColumn)))
|
||||
+ " FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)) + " GROUP BY a." + sqlkey;
|
||||
if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(entityClass.getSimpleName() + " single sql=" + sql);
|
||||
@@ -1209,31 +1195,30 @@ public final class DataDefaultSource implements DataSource, Nameable, Function<C
|
||||
|
||||
@Override
|
||||
public <T> T findByColumn(final Class<T> clazz, final String column, final Serializable key) {
|
||||
return find(clazz, null, FilterNode.create(column, key), null);
|
||||
return find(clazz, null, FilterNode.create(column, key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T find(final Class<T> clazz, final FilterBean bean) {
|
||||
return find(clazz, null, null, bean);
|
||||
return find(clazz, null, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T find(final Class<T> clazz, final FilterNode node) {
|
||||
return find(clazz, null, node, null);
|
||||
return find(clazz, null, node);
|
||||
}
|
||||
|
||||
private <T> T find(final Class<T> clazz, final SelectColumn selects, FilterNode node, final FilterBean bean) {
|
||||
public <T> T find(final Class<T> clazz, final SelectColumn selects, final FilterNode node) {
|
||||
final EntityInfo<T> info = loadEntityInfo(clazz);
|
||||
final EntityCache<T> cache = info.getCache();
|
||||
if (node == null && bean != null) node = loadFilterBeanNode(bean.getClass());
|
||||
if (cache != null && cache.isFullLoaded() && (node == null || node.isCacheUseable(this))) return cache.find(selects, node, bean);
|
||||
if (cache != null && cache.isFullLoaded() && (node == null || node.isCacheUseable(this))) return cache.find(selects, node);
|
||||
|
||||
final Connection conn = createReadSQLConnection();
|
||||
try {
|
||||
final SelectColumn sels = selects;
|
||||
final Map<Class, String> joinTabalis = node == null ? null : node.getJoinTabalis();
|
||||
final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info);
|
||||
final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis, bean);
|
||||
final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis);
|
||||
final String sql = "SELECT a.* FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where));
|
||||
if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " find sql=" + sql);
|
||||
final PreparedStatement ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||
@@ -1273,26 +1258,21 @@ public final class DataDefaultSource implements DataSource, Nameable, Function<C
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean exists(final Class<T> clazz, final FilterNode node) {
|
||||
return exists(clazz, node, null);
|
||||
public <T> boolean exists(final Class<T> clazz, final FilterBean bean) {
|
||||
return exists(clazz, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean exists(final Class<T> clazz, final FilterBean bean) {
|
||||
return exists(clazz, null, bean);
|
||||
}
|
||||
|
||||
private <T> boolean exists(final Class<T> clazz, FilterNode node, final FilterBean bean) {
|
||||
public <T> boolean exists(final Class<T> clazz, final FilterNode node) {
|
||||
final EntityInfo<T> info = loadEntityInfo(clazz);
|
||||
final EntityCache<T> cache = info.getCache();
|
||||
if (node == null && bean != null) node = loadFilterBeanNode(bean.getClass());
|
||||
if (cache != null && cache.isFullLoaded() && (node == null || node.isCacheUseable(this))) return cache.exists(node, bean);
|
||||
if (cache != null && cache.isFullLoaded() && (node == null || node.isCacheUseable(this))) return cache.exists(node);
|
||||
|
||||
final Connection conn = createReadSQLConnection();
|
||||
try {
|
||||
final Map<Class, String> joinTabalis = node == null ? null : node.getJoinTabalis();
|
||||
final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info);
|
||||
final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis, bean);
|
||||
final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis);
|
||||
final String sql = "SELECT COUNT(" + info.getPrimarySQLColumn("a") + ") FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where));
|
||||
if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " exists sql=" + sql);
|
||||
final PreparedStatement ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||
@@ -1446,12 +1426,12 @@ public final class DataDefaultSource implements DataSource, Nameable, Function<C
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryList(final Class<T> clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) {
|
||||
return querySheet(true, false, clazz, selects, flipper, node, null).list(true);
|
||||
return querySheet(true, false, clazz, selects, flipper, node).list(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryList(final Class<T> clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean) {
|
||||
return querySheet(true, false, clazz, selects, flipper, null, bean).list(true);
|
||||
return querySheet(true, false, clazz, selects, flipper, FilterNodeBean.createFilterNode(bean)).list(true);
|
||||
}
|
||||
|
||||
//-----------------------sheet----------------------------
|
||||
@@ -1468,16 +1448,12 @@ public final class DataDefaultSource implements DataSource, Nameable, Function<C
|
||||
*/
|
||||
@Override
|
||||
public <T, V> Sheet<V> queryColumnSheet(String selectedColumn, Class<T> clazz, final Flipper flipper, final FilterBean bean) {
|
||||
return queryColumnSheet(selectedColumn, clazz, flipper, null, bean);
|
||||
return queryColumnSheet(selectedColumn, clazz, flipper, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, V> Sheet<V> queryColumnSheet(String selectedColumn, Class<T> clazz, final Flipper flipper, final FilterNode node) {
|
||||
return queryColumnSheet(selectedColumn, clazz, flipper, node, null);
|
||||
}
|
||||
|
||||
private <T, V> Sheet<V> queryColumnSheet(String selectedColumn, Class<T> clazz, final Flipper flipper, final FilterNode node, final FilterBean bean) {
|
||||
Sheet<T> sheet = querySheet(true, true, clazz, SelectColumn.createIncludes(selectedColumn), flipper, node, bean);
|
||||
Sheet<T> sheet = querySheet(true, true, clazz, SelectColumn.createIncludes(selectedColumn), flipper, node);
|
||||
final Sheet<V> rs = new Sheet<>();
|
||||
if (sheet.isEmpty()) return rs;
|
||||
rs.setTotal(sheet.getTotal());
|
||||
@@ -1522,22 +1498,21 @@ public final class DataDefaultSource implements DataSource, Nameable, Function<C
|
||||
*/
|
||||
@Override
|
||||
public <T> Sheet<T> querySheet(Class<T> clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean) {
|
||||
return querySheet(true, true, clazz, selects, flipper, null, bean);
|
||||
return querySheet(true, true, clazz, selects, flipper, FilterNodeBean.createFilterNode(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Sheet<T> querySheet(Class<T> clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) {
|
||||
return querySheet(true, true, clazz, selects, flipper, node, null);
|
||||
return querySheet(true, true, clazz, selects, flipper, node);
|
||||
}
|
||||
|
||||
private <T> Sheet<T> querySheet(boolean readcache, boolean needtotal, Class<T> clazz, final SelectColumn selects, final Flipper flipper, FilterNode node, final FilterBean bean) {
|
||||
private <T> Sheet<T> querySheet(boolean readcache, boolean needtotal, Class<T> clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) {
|
||||
final EntityInfo<T> info = loadEntityInfo(clazz);
|
||||
final EntityCache<T> cache = info.getCache();
|
||||
if (node == null && bean != null) node = loadFilterBeanNode(bean.getClass());
|
||||
if (readcache && cache != null) {
|
||||
if (node == null || node.isCacheUseable(this)) {
|
||||
if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " cache query predicate = " + (node == null ? null : node.createPredicate(cache, bean)));
|
||||
Sheet<T> sheet = cache.querySheet(needtotal, selects, flipper, node, bean);
|
||||
if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " cache query predicate = " + (node == null ? null : node.createPredicate(cache)));
|
||||
Sheet<T> sheet = cache.querySheet(needtotal, selects, flipper, node);
|
||||
if (!sheet.isEmpty() || info.isVirtualEntity() || cache.isFullLoaded()) return sheet;
|
||||
}
|
||||
}
|
||||
@@ -1547,7 +1522,7 @@ public final class DataDefaultSource implements DataSource, Nameable, Function<C
|
||||
final List<T> list = new ArrayList();
|
||||
final Map<Class, String> joinTabalis = node == null ? null : node.getJoinTabalis();
|
||||
final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info);
|
||||
final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis, bean);
|
||||
final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis);
|
||||
final String sql = "SELECT a.* FROM " + info.getTable() + " a" + (join == null ? "" : join)
|
||||
+ ((where == null || where.length() == 0) ? "" : (" WHERE " + where)) + info.createSQLOrderby(flipper);
|
||||
if (debug.get() && info.isLoggable(Level.FINEST))
|
||||
|
||||
@@ -104,12 +104,7 @@ public final class EntityCache<T> {
|
||||
}
|
||||
|
||||
public T find(final SelectColumn selects, FilterNode node) {
|
||||
return find(selects, node, null);
|
||||
}
|
||||
|
||||
public T find(final SelectColumn selects, FilterNode node, final FilterBean bean) {
|
||||
if (node == null && bean != null) node = FilterBeanNode.load(bean.getClass());
|
||||
final Predicate<T> filter = node == null ? null : node.createPredicate(this, bean);
|
||||
final Predicate<T> filter = node == null ? null : node.createPredicate(this);
|
||||
Stream<T> stream = this.list.stream();
|
||||
if (filter != null) stream = stream.filter(filter);
|
||||
Optional<T> opt = stream.findFirst();
|
||||
@@ -144,9 +139,8 @@ public final class EntityCache<T> {
|
||||
return this.map.containsKey(id);
|
||||
}
|
||||
|
||||
public boolean exists(FilterNode node, final FilterBean bean) {
|
||||
if (node == null && bean != null) node = FilterBeanNode.load(bean.getClass());
|
||||
final Predicate<T> filter = node == null ? null : node.createPredicate(this, bean);
|
||||
public boolean exists(FilterNode node) {
|
||||
final Predicate<T> filter = node == null ? null : node.createPredicate(this);
|
||||
Stream<T> stream = this.list.stream();
|
||||
if (filter != null) stream = stream.filter(filter);
|
||||
return stream.findFirst().isPresent();
|
||||
@@ -156,14 +150,9 @@ public final class EntityCache<T> {
|
||||
return (filter != null) && this.list.stream().filter(filter).findFirst().isPresent();
|
||||
}
|
||||
|
||||
public <K, V> Map<Serializable, Number> getMapResult(final String keyColumn, final Reckon reckon, final String reckonColumn, final FilterNode node) {
|
||||
return getMapResult(keyColumn, reckon, reckonColumn, node, null);
|
||||
}
|
||||
|
||||
public <K, V> Map<Serializable, Number> getMapResult(final String keyColumn, final Reckon reckon, final String reckonColumn, FilterNode node, final FilterBean bean) {
|
||||
if (node == null && bean != null) node = FilterBeanNode.load(bean.getClass());
|
||||
public <K, V> Map<Serializable, Number> getMapResult(final String keyColumn, final Reckon reckon, final String reckonColumn, FilterNode node) {
|
||||
final Attribute<T, Serializable> keyAttr = info.getAttribute(keyColumn);
|
||||
final Predicate filter = node == null ? null : node.createPredicate(this, bean);
|
||||
final Predicate filter = node == null ? null : node.createPredicate(this);
|
||||
final Attribute reckonAttr = reckonColumn == null ? null : info.getAttribute(reckonColumn);
|
||||
Stream<T> stream = this.list.stream();
|
||||
if (filter != null) stream = stream.filter(filter);
|
||||
@@ -210,14 +199,9 @@ public final class EntityCache<T> {
|
||||
return rs;
|
||||
}
|
||||
|
||||
public <V> Number getNumberResult(final Reckon reckon, final String column, final FilterNode node) {
|
||||
return getNumberResult(reckon, column, node, null);
|
||||
}
|
||||
|
||||
public <V> Number getNumberResult(final Reckon reckon, final String column, FilterNode node, final FilterBean bean) {
|
||||
if (node == null && bean != null) node = FilterBeanNode.load(bean.getClass());
|
||||
public <V> Number getNumberResult(final Reckon reckon, final String column, FilterNode node) {
|
||||
final Attribute<T, Serializable> attr = column == null ? null : info.getAttribute(column);
|
||||
final Predicate<T> filter = node == null ? null : node.createPredicate(this, bean);
|
||||
final Predicate<T> filter = node == null ? null : node.createPredicate(this);
|
||||
Stream<T> stream = this.list.stream();
|
||||
if (filter != null) stream = stream.filter(filter);
|
||||
switch (reckon) {
|
||||
@@ -283,20 +267,11 @@ public final class EntityCache<T> {
|
||||
}
|
||||
|
||||
public Sheet<T> querySheet(final SelectColumn selects, final Flipper flipper, final FilterNode node) {
|
||||
return querySheet(selects, flipper, node, null);
|
||||
return querySheet(true, selects, flipper, node);
|
||||
}
|
||||
|
||||
public Sheet<T> querySheet(final SelectColumn selects, final Flipper flipper, final FilterNode node, final FilterBean bean) {
|
||||
return querySheet(true, selects, flipper, node, bean);
|
||||
}
|
||||
|
||||
public Sheet<T> querySheet(final boolean needtotal, final SelectColumn selects, final Flipper flipper, final FilterNode node) {
|
||||
return querySheet(needtotal, selects, flipper, node, null);
|
||||
}
|
||||
|
||||
public Sheet<T> querySheet(final boolean needtotal, final SelectColumn selects, final Flipper flipper, FilterNode node, final FilterBean bean) {
|
||||
if (node == null && bean != null) node = FilterBeanNode.load(bean.getClass());
|
||||
final Predicate<T> filter = node == null ? null : node.createPredicate(this, bean);
|
||||
public Sheet<T> querySheet(final boolean needtotal, final SelectColumn selects, final Flipper flipper, FilterNode node) {
|
||||
final Predicate<T> filter = node == null ? null : node.createPredicate(this);
|
||||
final Comparator<T> comparator = createComparator(flipper);
|
||||
long total = 0;
|
||||
if (needtotal) {
|
||||
@@ -358,7 +333,7 @@ public final class EntityCache<T> {
|
||||
|
||||
public Serializable[] delete(final FilterNode node) {
|
||||
if (node == null || this.list.isEmpty()) return new Serializable[0];
|
||||
Object[] rms = this.list.stream().filter(node.createPredicate(this, null)).toArray();
|
||||
Object[] rms = this.list.stream().filter(node.createPredicate(this)).toArray();
|
||||
Serializable[] ids = new Serializable[rms.length];
|
||||
int i = -1;
|
||||
for (Object o : rms) {
|
||||
|
||||
@@ -1,387 +0,0 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.source;
|
||||
|
||||
import static com.wentch.redkale.source.FilterExpress.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.*;
|
||||
import java.util.logging.Logger;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
final class FilterBeanNode extends FilterNode {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(FilterBeanNode.class.getSimpleName());
|
||||
|
||||
private static final ConcurrentHashMap<Class, FilterBeanNode> beanodes = new ConcurrentHashMap<>();
|
||||
|
||||
public static <T extends FilterBean> FilterBeanNode load(Class<T> clazz) {
|
||||
return load(clazz, -1, true, null);
|
||||
}
|
||||
|
||||
public static <T extends FilterBean> FilterBeanNode load(Class<T> clazz, final int nodeid, final boolean cacheForbidden,
|
||||
Function<Class, List> fullloader) {
|
||||
FilterBeanNode rs = beanodes.get(clazz);
|
||||
if (rs != null) return rs;
|
||||
synchronized (beanodes) {
|
||||
rs = beanodes.get(clazz);
|
||||
if (rs == null) {
|
||||
rs = createNode(clazz, nodeid, cacheForbidden, fullloader);
|
||||
beanodes.put(clazz, rs);
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends FilterBean> FilterBeanNode createNode(Class<T> clazz, final int nodeid, final boolean cacheForbidden,
|
||||
Function<Class, List> fullloader) {
|
||||
Class cltmp = clazz;
|
||||
Set<String> fields = new HashSet<>();
|
||||
final Map<Class, String> joinTables = new HashMap<>();
|
||||
Map<String, FilterBeanNode> nodemap = new HashMap<>();
|
||||
boolean joinallcached = true;
|
||||
final StringBuilder joinsb = new StringBuilder();
|
||||
do {
|
||||
for (Field field : cltmp.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(field.getModifiers())) continue;
|
||||
if (fields.contains(field.getName())) continue;
|
||||
if (field.getAnnotation(Ignore.class) != null) continue;
|
||||
if (field.getAnnotation(Transient.class) != null) continue;
|
||||
|
||||
final boolean pubmod = Modifier.isPublic(field.getModifiers());
|
||||
|
||||
char[] chars = field.getName().toCharArray();
|
||||
chars[0] = Character.toUpperCase(chars[0]);
|
||||
final Class t = field.getType();
|
||||
Method getter = null;
|
||||
try {
|
||||
getter = cltmp.getMethod(((t == boolean.class || t == Boolean.class) ? "is" : "get") + new String(chars));
|
||||
} catch (Exception ex) {
|
||||
if (!pubmod) continue;
|
||||
}
|
||||
fields.add(field.getName());
|
||||
FilterBeanNode newnode = new FilterBeanNode(field.getName(), true, pubmod ? Attribute.create(field) : Attribute.create(getter, null));
|
||||
newnode.setField(field);
|
||||
//------------------------------------
|
||||
{
|
||||
FilterJoinColumn joinCol = field.getAnnotation(FilterJoinColumn.class);
|
||||
if (joinCol != null) {
|
||||
boolean first = false;
|
||||
final Class joinClass = joinCol.table();
|
||||
if (!joinTables.containsKey(joinClass)) {
|
||||
first = true;
|
||||
joinTables.put(joinClass, String.valueOf((char) ('b' + joinTables.size())));
|
||||
}
|
||||
final String alias = joinTables.get(joinClass);
|
||||
final EntityInfo secinfo = EntityInfo.load(joinClass, nodeid, cacheForbidden, fullloader);
|
||||
if (secinfo.getCache() == null || !secinfo.getCache().isFullLoaded()) {
|
||||
joinallcached = false;
|
||||
}
|
||||
final String jc = joinCol.column().isEmpty() ? secinfo.getPrimary().field() : joinCol.column();
|
||||
if (first) {
|
||||
joinsb.append(" INNER JOIN ").append(secinfo.getTable())
|
||||
.append(" ").append(alias).append(" ON ").append(secinfo.getSQLColumn("a", jc)).append(" = ").append(secinfo.getSQLColumn(alias, jc));
|
||||
}
|
||||
newnode.foreignCache = secinfo.getCache();
|
||||
newnode.tabalis = alias;
|
||||
newnode.columnAttribute = secinfo.getAttribute(newnode.column);
|
||||
newnode.byjoinColumn = jc;
|
||||
newnode.foreignAttribute = secinfo.getAttribute(jc);
|
||||
if (newnode.foreignCache != null && newnode.foreignAttribute == null) throw new RuntimeException(clazz.getName() + "." + field.getName() + " have illegal FilterJoinColumn " + joinCol);
|
||||
}
|
||||
}
|
||||
//------------------------------------
|
||||
{
|
||||
FilterGroup[] refs = field.getAnnotationsByType(FilterGroup.class);
|
||||
String[] groups = new String[refs.length];
|
||||
for (int i = 0; i < refs.length; i++) {
|
||||
groups[i] = refs[i].value();
|
||||
}
|
||||
if (groups.length == 0) groups = new String[]{"[AND]"};
|
||||
for (String key : groups) {
|
||||
if (!key.startsWith("[AND]") && !key.startsWith("[OR]")) {
|
||||
throw new RuntimeException(field + "'s FilterGroup.value(" + key + ") illegal, must be [AND] or [OR] startsWith");
|
||||
}
|
||||
FilterBeanNode node = nodemap.get(key);
|
||||
if (node == null) {
|
||||
nodemap.put(key, newnode);
|
||||
} else {
|
||||
node.any(newnode, key.contains("[OR]"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ((cltmp = cltmp.getSuperclass()) != Object.class);
|
||||
FilterBeanNode rs = null;
|
||||
for (FilterBeanNode f : nodemap.values()) {
|
||||
if (rs == null) {
|
||||
rs = f;
|
||||
} else {
|
||||
rs.and(f);
|
||||
}
|
||||
}
|
||||
if (rs != null) {
|
||||
rs.joinallcached = joinallcached;
|
||||
if (joinsb.length() > 0) rs.joinSQL = joinsb.toString();
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
|
||||
//--------------------------- only header -----------------------------------------------------
|
||||
private boolean joinallcached = true;
|
||||
|
||||
private String joinSQL;
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
private Attribute beanAttribute;
|
||||
|
||||
private EntityCache foreignCache; // join 表
|
||||
|
||||
private String byjoinColumn; //被join表的join字段
|
||||
|
||||
private Attribute foreignAttribute; //join表的join字段
|
||||
|
||||
private Attribute columnAttribute;
|
||||
|
||||
private String tabalis;
|
||||
|
||||
private long least;
|
||||
|
||||
private boolean string;
|
||||
|
||||
private boolean number;
|
||||
|
||||
protected FilterBeanNode(String col, boolean sign, Attribute beanAttr) {
|
||||
this.column = col;
|
||||
this.or = sign;
|
||||
this.beanAttribute = beanAttr;
|
||||
}
|
||||
|
||||
private void setField(Field field) {
|
||||
final FilterColumn fc = field.getAnnotation(FilterColumn.class);
|
||||
if (fc != null && !fc.name().isEmpty()) this.column = fc.name();
|
||||
final Class type = field.getType();
|
||||
this.least = fc == null ? 1L : fc.least();
|
||||
this.number = (type.isPrimitive() && type != boolean.class) || Number.class.isAssignableFrom(type);
|
||||
this.string = CharSequence.class.isAssignableFrom(type);
|
||||
|
||||
FilterExpress exp = fc == null ? null : fc.express();
|
||||
if (type.isArray() || Collection.class.isAssignableFrom(type)) {
|
||||
if (Range.class.isAssignableFrom(type.getComponentType())) {
|
||||
if (AND != exp) exp = OR;
|
||||
} else if (NOTIN != exp) exp = IN;
|
||||
} else if (Range.class.isAssignableFrom(type)) {
|
||||
if (NOTBETWEEN != exp) exp = BETWEEN;
|
||||
}
|
||||
if (exp == null) exp = EQUAL;
|
||||
this.express = exp;
|
||||
this.tabalis = "a";
|
||||
}
|
||||
|
||||
protected String getTabalis() {
|
||||
return tabalis;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void append(FilterNode node, boolean sign) {
|
||||
FilterBeanNode newnode = new FilterBeanNode(this.column, this.or, this.beanAttribute);
|
||||
newnode.express = this.express;
|
||||
newnode.nodes = this.nodes;
|
||||
newnode.foreignCache = this.foreignCache;
|
||||
newnode.byjoinColumn = this.byjoinColumn;
|
||||
newnode.foreignAttribute = this.foreignAttribute;
|
||||
newnode.columnAttribute = this.columnAttribute;
|
||||
newnode.least = this.least;
|
||||
newnode.number = this.number;
|
||||
newnode.string = this.string;
|
||||
this.nodes = new FilterNode[]{newnode};
|
||||
this.column = node.column;
|
||||
this.express = node.express;
|
||||
this.or = sign;
|
||||
this.setValue(node.getValue());
|
||||
if (node instanceof FilterBeanNode) {
|
||||
FilterBeanNode beanNode = ((FilterBeanNode) node);
|
||||
this.beanAttribute = beanNode.beanAttribute;
|
||||
this.foreignCache = beanNode.foreignCache;
|
||||
this.byjoinColumn = beanNode.byjoinColumn;
|
||||
this.foreignAttribute = beanNode.foreignAttribute;
|
||||
this.columnAttribute = beanNode.columnAttribute;
|
||||
this.least = beanNode.least;
|
||||
this.number = beanNode.number;
|
||||
this.string = beanNode.string;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> CharSequence createSQLJoin(final Function<Class, EntityInfo> func, final Map<Class, String> joinTabalis, final EntityInfo<T> info) {
|
||||
if (joinSQL == null) return null;
|
||||
return joinSQL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T, E> Predicate<T> createPredicate(final EntityCache<T> cache, FilterBean bean) {
|
||||
if (this.foreignCache == null) return super.createPredicate(cache, bean);
|
||||
final Map<EntityCache, Predicate> foreign = new HashMap<>();
|
||||
Predicate<T> result = null;
|
||||
putForeignPredicate(cache, foreign, bean);
|
||||
if (this.nodes != null) {
|
||||
for (FilterNode n : this.nodes) {
|
||||
FilterBeanNode node = (FilterBeanNode) n;
|
||||
if (node.foreignCache == null) {
|
||||
Predicate<T> f = node.createPredicate(cache, bean);
|
||||
if (f == null) continue;
|
||||
final Predicate<T> one = result;
|
||||
final Predicate<T> two = f;
|
||||
result = (result == 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 + ")";
|
||||
}
|
||||
});
|
||||
} else {
|
||||
putForeignPredicate(cache, foreign, bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (foreign.isEmpty()) return result;
|
||||
final String byjoinCol = this.byjoinColumn;
|
||||
final Attribute foreignAttr = this.foreignAttribute;
|
||||
for (final Map.Entry<EntityCache, Predicate> en : foreign.entrySet()) {
|
||||
Attribute<T, Serializable> byjoinAttr = cache.getAttribute(byjoinCol);
|
||||
final Predicate p = en.getValue();
|
||||
final EntityCache joinCache = en.getKey();
|
||||
Predicate<T> f = new Predicate<T>() {
|
||||
|
||||
@Override
|
||||
public boolean test(T t) {
|
||||
Serializable key = byjoinAttr.get(t);
|
||||
Predicate k = (e) -> key.equals(foreignAttr.get(e));
|
||||
return joinCache.exists(k.and(p));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + byjoinAttr.field() + " = " + en.getKey().getType().getSimpleName() + "." + foreignAttr.field() + " AND " + p + ")";
|
||||
}
|
||||
};
|
||||
final Predicate<T> one = result;
|
||||
final Predicate<T> two = f;
|
||||
result = (result == 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 + ")";
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private <T> void putForeignPredicate(final EntityCache<T> cache, final Map<EntityCache, Predicate> foreign, FilterBean bean) {
|
||||
if (this.foreignCache == null) return;
|
||||
final Serializable val = getElementValue(bean);
|
||||
Predicate filter = (val == null && express != ISNULL && express != ISNOTNULL) ? new Predicate<T>() {
|
||||
|
||||
@Override
|
||||
public boolean test(T t) {
|
||||
return or;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "" + or;
|
||||
}
|
||||
} : super.createElementPredicate(cache, false, this.columnAttribute, bean);
|
||||
if (filter == null) return;
|
||||
Predicate p = foreign.get(this.foreignCache);
|
||||
if (p == null) {
|
||||
foreign.put(foreignCache, filter);
|
||||
} else {
|
||||
final Predicate<T> one = p;
|
||||
final Predicate<T> two = filter;
|
||||
p = 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 + ")";
|
||||
}
|
||||
};
|
||||
foreign.put(foreignCache, p);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCacheUseable(final Function<Class, EntityInfo> entityApplyer) {
|
||||
return joinallcached;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Serializable getElementValue(FilterBean bean) {
|
||||
if (bean == null || beanAttribute == null) return null;
|
||||
Serializable rs = (Serializable) beanAttribute.get(bean);
|
||||
if (rs == null) return null;
|
||||
if (string && ((CharSequence) rs).length() == 0) return null;
|
||||
if (number && ((Number) rs).longValue() < this.least) return null;
|
||||
return rs;
|
||||
}
|
||||
}
|
||||
@@ -56,15 +56,21 @@ public class FilterJoinNode extends FilterNode {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> CharSequence createSQLExpress(final EntityInfo<T> info, final Map<Class, String> joinTabalis, final FilterBean bean) {
|
||||
return super.createSQLExpress(this.joinEntity, joinTabalis, bean);
|
||||
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());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T, E> Predicate<T> createPredicate(final EntityCache<T> cache, final FilterBean bean) {
|
||||
protected <T> CharSequence createSQLExpress(final EntityInfo<T> info, final Map<Class, String> joinTabalis) {
|
||||
return super.createSQLExpress(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(bean);
|
||||
Predicate<E> filter = createChildPredicate();
|
||||
if (filter == null) return null;
|
||||
|
||||
final Predicate<E> inner = filter;
|
||||
@@ -95,13 +101,13 @@ public class FilterJoinNode extends FilterNode {
|
||||
};
|
||||
}
|
||||
|
||||
private <E> Predicate<E> createChildPredicate(final FilterBean bean) {
|
||||
private <E> Predicate<E> createChildPredicate() {
|
||||
if (column == null && this.nodes == null) return null;
|
||||
final EntityCache<E> joinCache = this.joinEntity.getCache();
|
||||
Predicate<E> filter = createElementPredicate(joinCache, true, bean);
|
||||
Predicate<E> filter = createElementPredicate(joinCache, true);
|
||||
if (this.nodes != null) {
|
||||
for (FilterNode node : this.nodes) {
|
||||
Predicate<E> f = ((FilterJoinNode) node).createChildPredicate(bean);
|
||||
Predicate<E> f = ((FilterJoinNode) node).createChildPredicate();
|
||||
if (f == null) continue;
|
||||
final Predicate<E> one = filter;
|
||||
final Predicate<E> two = f;
|
||||
@@ -181,13 +187,7 @@ public class FilterJoinNode extends FilterNode {
|
||||
|
||||
@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(toString(joinClass == null ? null : joinClass.getSimpleName(), null));
|
||||
return sb.toString();
|
||||
return toString(joinClass == null ? null : joinClass.getSimpleName()).toString();
|
||||
}
|
||||
|
||||
public Class getJoinClass() {
|
||||
|
||||
@@ -77,7 +77,7 @@ public class FilterNode {
|
||||
return or(new FilterNode(column, express, value));
|
||||
}
|
||||
|
||||
protected final FilterNode any(FilterNode node, boolean sign) {
|
||||
protected final FilterNode any(FilterNode node, boolean signor) {
|
||||
Objects.requireNonNull(node);
|
||||
if (this.column == null) {
|
||||
this.column = node.column;
|
||||
@@ -87,17 +87,24 @@ public class FilterNode {
|
||||
}
|
||||
if (this.nodes == null) {
|
||||
this.nodes = new FilterNode[]{node};
|
||||
this.or = sign;
|
||||
this.or = signor;
|
||||
return this;
|
||||
}
|
||||
if (or == sign) {
|
||||
if (or == signor) {
|
||||
FilterNode[] newsiblings = new FilterNode[nodes.length + 1];
|
||||
System.arraycopy(nodes, 0, newsiblings, 0, nodes.length);
|
||||
newsiblings[nodes.length] = node;
|
||||
this.nodes = newsiblings;
|
||||
return this;
|
||||
}
|
||||
this.append(node, sign);
|
||||
FilterNode newnode = new FilterNode(this.column, this.express, this.value);
|
||||
newnode.or = this.or;
|
||||
newnode.nodes = this.nodes;
|
||||
this.nodes = new FilterNode[]{newnode, node};
|
||||
this.column = null;
|
||||
this.express = null;
|
||||
this.or = signor;
|
||||
this.value = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -105,27 +112,9 @@ public class FilterNode {
|
||||
* 该方法需要重载
|
||||
*
|
||||
* @param node
|
||||
* @param sign
|
||||
*/
|
||||
protected void append(FilterNode node, boolean sign) {
|
||||
FilterNode newnode = new FilterNode(this.column, this.express, this.value);
|
||||
newnode.or = this.or;
|
||||
newnode.nodes = this.nodes;
|
||||
this.nodes = new FilterNode[]{newnode, node};
|
||||
this.column = null;
|
||||
this.express = null;
|
||||
this.or = sign;
|
||||
this.value = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 该方法需要重载
|
||||
*
|
||||
* @param bean
|
||||
* @return
|
||||
*/
|
||||
protected Serializable getElementValue(final FilterBean bean) {
|
||||
return value;
|
||||
protected void check(FilterNode node) {
|
||||
Objects.requireNonNull(node);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,8 +188,8 @@ public class FilterNode {
|
||||
* @param bean
|
||||
* @return
|
||||
*/
|
||||
protected <T> CharSequence createSQLExpress(final EntityInfo<T> info, final Map<Class, String> joinTabalis, final FilterBean bean) {
|
||||
CharSequence sb0 = createElementSQLExpress(info, joinTabalis == null ? null : joinTabalis.get(info.getType()), bean);
|
||||
protected <T> CharSequence createSQLExpress(final EntityInfo<T> info, final Map<Class, String> joinTabalis) {
|
||||
CharSequence sb0 = createElementSQLExpress(info, joinTabalis == null ? null : joinTabalis.get(info.getType()));
|
||||
if (this.nodes == null) return sb0;
|
||||
final StringBuilder rs = new StringBuilder();
|
||||
rs.append('(');
|
||||
@@ -210,7 +199,7 @@ public class FilterNode {
|
||||
rs.append(sb0);
|
||||
}
|
||||
for (FilterNode node : this.nodes) {
|
||||
CharSequence f = node.createSQLExpress(info, joinTabalis, bean);
|
||||
CharSequence f = node.createSQLExpress(info, joinTabalis);
|
||||
if (f == null || f.length() < 3) continue;
|
||||
if (more) rs.append(or ? " OR " : " AND ");
|
||||
rs.append(f);
|
||||
@@ -229,13 +218,13 @@ public class FilterNode {
|
||||
return new FilterNode(column, express, value);
|
||||
}
|
||||
|
||||
protected final <T> CharSequence createElementSQLExpress(final EntityInfo<T> info, String talis, final FilterBean bean) {
|
||||
protected final <T> CharSequence createElementSQLExpress(final EntityInfo<T> info, String talis) {
|
||||
if (column == null) return null;
|
||||
if (talis == null) talis = "a";
|
||||
if (express == ISNULL || express == ISNOTNULL) {
|
||||
return new StringBuilder().append(info.getSQLColumn(talis, column)).append(' ').append(express.value());
|
||||
}
|
||||
final CharSequence val = formatToString(express, getElementValue(bean));
|
||||
final CharSequence val = formatToString(express, getValue());
|
||||
if (val == null) return null;
|
||||
StringBuilder sb = new StringBuilder(32);
|
||||
if (express == IGNORECASELIKE || express == IGNORECASENOTLIKE) {
|
||||
@@ -259,12 +248,12 @@ public class FilterNode {
|
||||
return sb;
|
||||
}
|
||||
|
||||
protected <T, E> Predicate<T> createPredicate(final EntityCache<T> cache, final FilterBean bean) {
|
||||
protected <T, E> Predicate<T> createPredicate(final EntityCache<T> cache) {
|
||||
if (cache == null || (column == null && this.nodes == null)) return null;
|
||||
Predicate<T> filter = createElementPredicate(cache, false, bean);
|
||||
Predicate<T> filter = createElementPredicate(cache, false);
|
||||
if (this.nodes == null) return filter;
|
||||
for (FilterNode node : this.nodes) {
|
||||
Predicate<T> f = node.createPredicate(cache, bean);
|
||||
Predicate<T> f = node.createPredicate(cache);
|
||||
if (f == null) continue;
|
||||
final Predicate<T> one = filter;
|
||||
final Predicate<T> two = f;
|
||||
@@ -295,12 +284,12 @@ public class FilterNode {
|
||||
return filter;
|
||||
}
|
||||
|
||||
protected final <T> Predicate<T> createElementPredicate(final EntityCache<T> cache, final boolean join, final FilterBean bean) {
|
||||
protected final <T> Predicate<T> createElementPredicate(final EntityCache<T> cache, final boolean join) {
|
||||
if (column == null) return null;
|
||||
return createElementPredicate(cache, join, cache.getAttribute(column), bean);
|
||||
return createElementPredicate(cache, join, cache.getAttribute(column));
|
||||
}
|
||||
|
||||
protected final <T> Predicate<T> createElementPredicate(final EntityCache<T> cache, final boolean join, final Attribute<T, Serializable> attr, final FilterBean bean) {
|
||||
protected final <T> Predicate<T> createElementPredicate(final EntityCache<T> cache, final boolean join, final Attribute<T, Serializable> attr) {
|
||||
if (attr == null) return null;
|
||||
final String field = join ? (cache.getType().getSimpleName() + "." + attr.field()) : attr.field();
|
||||
if (express == ISNULL) return new Predicate<T>() {
|
||||
@@ -328,7 +317,7 @@ public class FilterNode {
|
||||
}
|
||||
};
|
||||
if (attr == null) return null;
|
||||
Serializable val0 = getElementValue(bean);
|
||||
Serializable val0 = getValue();
|
||||
if (val0 == null) return null;
|
||||
|
||||
final Class atype = attr.type();
|
||||
@@ -833,43 +822,39 @@ public class FilterNode {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(null, null);
|
||||
return toString(null).toString();
|
||||
}
|
||||
|
||||
protected String toString(final String prefix, final FilterBean bean) {
|
||||
protected StringBuilder toString(final String prefix) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (nodes == null) {
|
||||
if (column != null) {
|
||||
String col = prefix == null ? column : (prefix + "." + column);
|
||||
Serializable ev = getElementValue(bean);
|
||||
if (express == ISNULL || express == ISNOTNULL) {
|
||||
sb.append(col).append(' ').append(express.value());
|
||||
} else if (ev != null) {
|
||||
sb.append((express == IGNORECASELIKE || express == IGNORECASENOTLIKE) ? ("LOWER(" + col + ')') : col).append(' ').append(express.value()).append(' ').append(formatToString(express, ev));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boolean more = false;
|
||||
if (column != null) {
|
||||
String col = prefix == null ? column : (prefix + "." + column);
|
||||
Serializable ev = getElementValue(bean);
|
||||
if (express == ISNULL || express == ISNOTNULL) {
|
||||
sb.append('(').append(col).append(' ').append(express.value());
|
||||
more = true;
|
||||
} else if (ev != null) {
|
||||
sb.append('(').append((express == IGNORECASELIKE || express == IGNORECASENOTLIKE) ? ("LOWER(" + col + ')') : col).append(' ').append(express.value()).append(' ').append(formatToString(express, ev));
|
||||
more = true;
|
||||
}
|
||||
}
|
||||
StringBuilder element = toElementString(prefix);
|
||||
boolean more = element.length() > 0 && this.nodes != null;
|
||||
if (more) sb.append('(');
|
||||
sb.append(element);
|
||||
if (this.nodes != null) {
|
||||
for (FilterNode node : this.nodes) {
|
||||
String s = node.toString();
|
||||
if (s.isEmpty()) continue;
|
||||
if (sb.length() > 0) sb.append(or ? " OR " : " AND ");
|
||||
if (s.length() < 1) continue;
|
||||
if (sb.length() > 1) sb.append(or ? " OR " : " AND ");
|
||||
sb.append(s);
|
||||
}
|
||||
if (more) sb.append(')');
|
||||
}
|
||||
return sb.toString();
|
||||
if (more) sb.append(')');
|
||||
return sb;
|
||||
}
|
||||
|
||||
protected final StringBuilder toElementString(final String prefix) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (column != null) {
|
||||
String col = prefix == null ? column : (prefix + "." + column);
|
||||
Serializable ev = getValue();
|
||||
if (express == ISNULL || express == ISNOTNULL) {
|
||||
sb.append(col).append(' ').append(express.value());
|
||||
} else if (ev != null) {
|
||||
sb.append((express == IGNORECASELIKE || express == IGNORECASENOTLIKE) ? ("LOWER(" + col + ')') : col).append(' ').append(express.value()).append(' ').append(formatToString(express, ev));
|
||||
}
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
protected static CharSequence formatToString(Object value) {
|
||||
|
||||
351
src/com/wentch/redkale/source/FilterNodeBean.java
Normal file
351
src/com/wentch/redkale/source/FilterNodeBean.java
Normal file
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.source;
|
||||
|
||||
import static com.wentch.redkale.source.FilterExpress.*;
|
||||
import com.wentch.redkale.util.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import javax.persistence.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public final class FilterNodeBean<T> implements Comparable<FilterNodeBean<T>> {
|
||||
|
||||
private static final ConcurrentHashMap<Class, FilterNodeBean> beanodes = new ConcurrentHashMap<>();
|
||||
|
||||
private Attribute<T, Serializable> beanAttr;
|
||||
|
||||
private String column;
|
||||
|
||||
private FilterExpress express;
|
||||
|
||||
private boolean or;
|
||||
|
||||
private FilterNodeBean[] nodeBeans;
|
||||
|
||||
//-----------------join table--------------------------
|
||||
private Class joinClass;
|
||||
|
||||
private String[] joinColumns;
|
||||
|
||||
//----------------------------------------------------
|
||||
private long least;
|
||||
|
||||
private boolean string;
|
||||
|
||||
private boolean number;
|
||||
|
||||
public FilterNodeBean(FilterNodeBean bean) {
|
||||
this.beanAttr = bean.beanAttr;
|
||||
this.column = bean.column;
|
||||
this.express = bean.express;
|
||||
this.joinClass = bean.joinClass;
|
||||
this.joinColumns = bean.joinColumns;
|
||||
this.least = bean.least;
|
||||
this.string = bean.string;
|
||||
this.number = bean.number;
|
||||
this.or = bean.or;
|
||||
this.nodeBeans = bean.nodeBeans;
|
||||
}
|
||||
|
||||
private FilterNodeBean(final FilterJoinColumn joinCol, final FilterColumn filterCol, final Attribute<T, Serializable> attr) {
|
||||
this.beanAttr = attr;
|
||||
this.joinClass = joinCol == null ? null : joinCol.table();
|
||||
this.joinColumns = joinCol == null ? null : (joinCol.columns().length == 0 ? new String[]{joinCol.column()} : joinCol.columns());
|
||||
|
||||
final Class type = attr.type();
|
||||
this.column = (filterCol != null && !filterCol.name().isEmpty()) ? filterCol.name() : attr.field();
|
||||
|
||||
FilterExpress exp = filterCol == null ? null : filterCol.express();
|
||||
if (type.isArray() || Collection.class.isAssignableFrom(type)) {
|
||||
if (Range.class.isAssignableFrom(type.getComponentType())) {
|
||||
if (AND != exp) exp = OR;
|
||||
} else if (NOTIN != exp) exp = IN;
|
||||
} else if (Range.class.isAssignableFrom(type)) {
|
||||
if (NOTBETWEEN != exp) exp = BETWEEN;
|
||||
}
|
||||
if (exp == null) exp = EQUAL;
|
||||
this.express = exp;
|
||||
|
||||
this.least = filterCol == null ? 1 : filterCol.least();
|
||||
this.number = (type.isPrimitive() && type != boolean.class) || Number.class.isAssignableFrom(type);
|
||||
this.string = CharSequence.class.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
private FilterNodeBean or(FilterNodeBean node) {
|
||||
return any(node, true);
|
||||
}
|
||||
|
||||
private FilterNodeBean and(FilterNodeBean node) {
|
||||
return any(node, false);
|
||||
}
|
||||
|
||||
private FilterNodeBean any(FilterNodeBean node, boolean signor) {
|
||||
Objects.requireNonNull(node);
|
||||
if (this.column == null) {
|
||||
this.beanAttr = node.beanAttr;
|
||||
this.column = node.column;
|
||||
this.express = node.express;
|
||||
this.joinClass = node.joinClass;
|
||||
this.joinColumns = node.joinColumns;
|
||||
this.least = node.least;
|
||||
this.string = node.string;
|
||||
this.number = node.number;
|
||||
return this;
|
||||
}
|
||||
if (this.nodeBeans == null) {
|
||||
this.nodeBeans = new FilterNodeBean[]{node};
|
||||
this.or = signor;
|
||||
return this;
|
||||
}
|
||||
if (or == signor) {
|
||||
FilterNodeBean[] newsiblings = new FilterNodeBean[nodeBeans.length + 1];
|
||||
System.arraycopy(nodeBeans, 0, newsiblings, 0, nodeBeans.length);
|
||||
newsiblings[nodeBeans.length] = node;
|
||||
this.nodeBeans = newsiblings;
|
||||
return this;
|
||||
}
|
||||
this.nodeBeans = new FilterNodeBean[]{new FilterNodeBean(this), node};
|
||||
this.column = null;
|
||||
this.or = signor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static FilterNode createFilterNode(final FilterBean bean) {
|
||||
if (bean == null) return null;
|
||||
return load(bean.getClass()).create(bean);
|
||||
}
|
||||
|
||||
private FilterNode create(final T bean) {
|
||||
if (bean == null) return null;
|
||||
FilterNode node = null;
|
||||
final Serializable val = beanAttr.get(bean);
|
||||
if (column != null && val != null) {
|
||||
boolean skip = false;
|
||||
if (string && ((CharSequence) val).length() == 0) {
|
||||
skip = true;
|
||||
} else if (number && ((Number) val).longValue() < least) {
|
||||
skip = true;
|
||||
}
|
||||
if (!skip) {
|
||||
if (this.joinClass == null) {
|
||||
node = FilterNode.create(column, express, val);
|
||||
} else {
|
||||
node = FilterJoinNode.create(joinClass, joinColumns, column, express, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.nodeBeans == null) return node;
|
||||
for (final FilterNodeBean fnb : this.nodeBeans) {
|
||||
FilterNode n = fnb.create(bean);
|
||||
if (n == null) continue;
|
||||
node = node == null ? n : ((!(n instanceof FilterJoinNode)) ? n.any(node, or) : node.any(n, or));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
private static <T extends FilterBean> FilterNodeBean createFilterNodeBean(final Class<T> clazz) {
|
||||
final Set<String> fields = new HashSet<>();
|
||||
final Map<String, FilterNodeBean> nodemap = new LinkedHashMap();
|
||||
Class cltmp = clazz;
|
||||
do {
|
||||
for (final Field field : cltmp.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(field.getModifiers())) continue;
|
||||
if (fields.contains(field.getName())) continue;
|
||||
if (field.getAnnotation(Ignore.class) != null) continue;
|
||||
if (field.getAnnotation(Transient.class) != null) continue;
|
||||
|
||||
final boolean pubmod = Modifier.isPublic(field.getModifiers());
|
||||
|
||||
char[] chars = field.getName().toCharArray();
|
||||
chars[0] = Character.toUpperCase(chars[0]);
|
||||
final Class t = field.getType();
|
||||
Method getter = null;
|
||||
try {
|
||||
getter = cltmp.getMethod(((t == boolean.class || t == Boolean.class) ? "is" : "get") + new String(chars));
|
||||
} catch (Exception ex) {
|
||||
if (!pubmod) continue;
|
||||
}
|
||||
fields.add(field.getName());
|
||||
|
||||
final Attribute<T, Serializable> beanAttr = pubmod ? Attribute.create(field) : Attribute.create(getter, null);
|
||||
FilterNodeBean<T> nodeBean = new FilterNodeBean(field.getAnnotation(FilterJoinColumn.class), field.getAnnotation(FilterColumn.class), beanAttr);
|
||||
|
||||
//------------------------------------
|
||||
{
|
||||
FilterGroup[] refs = field.getAnnotationsByType(FilterGroup.class);
|
||||
String[] groups = new String[refs.length];
|
||||
for (int i = 0; i < refs.length; i++) {
|
||||
groups[i] = refs[i].value();
|
||||
}
|
||||
if (groups.length == 0) groups = new String[]{"[AND]"};
|
||||
for (String key : groups) {
|
||||
if (!key.startsWith("[AND]") && !key.startsWith("[OR]")) {
|
||||
throw new RuntimeException(field + "'s FilterGroup.value(" + key + ") illegal, must be [AND] or [OR] startsWith");
|
||||
}
|
||||
FilterNodeBean node = nodemap.get(key);
|
||||
if (node == null) {
|
||||
nodemap.put(key, nodeBean);
|
||||
} else {
|
||||
node.any(nodeBean, key.substring(key.lastIndexOf('.') + 1).contains("[OR]"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ((cltmp = cltmp.getSuperclass()) != Object.class);
|
||||
final Map<String, LinkNode> linkes = new LinkedHashMap<>();
|
||||
nodemap.forEach((k, v) -> {
|
||||
String[] keys = k.split("\\.");
|
||||
LinkNode link = linkes.get(keys[0]);
|
||||
if (link == null) {
|
||||
linkes.put(keys[0], new LinkNode(k, v));
|
||||
} else {
|
||||
link.put(keys, 0, v);
|
||||
}
|
||||
});
|
||||
FilterNodeBean rs = null;
|
||||
for (LinkNode link : linkes.values()) {
|
||||
FilterNodeBean f = link.createFilterNodeBean();
|
||||
if (f == null) continue;
|
||||
rs = rs == null ? f : rs.and(f);
|
||||
}
|
||||
if (rs.nodeBeans != null) Arrays.sort(rs.nodeBeans);
|
||||
return rs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(FilterNodeBean<T> o) {
|
||||
if (this.joinClass == null && o.joinClass == null) return 0;
|
||||
if (this.joinClass != null && o.joinClass != null) return 0;
|
||||
return this.joinClass == null ? -1 : 1;
|
||||
}
|
||||
|
||||
private static class LinkNode {
|
||||
|
||||
public final boolean or;
|
||||
|
||||
public final String key;
|
||||
|
||||
public final List<FilterNodeBean> beans = new ArrayList<>();
|
||||
|
||||
public final Map<String, LinkNode> nexts = new LinkedHashMap<>();
|
||||
|
||||
public LinkNode(String keyString, FilterNodeBean node) {
|
||||
String[] keys = keyString.split("\\.");
|
||||
this.key = keys[0];
|
||||
this.or = this.key.contains("[OR]");
|
||||
put(keys, 0, node);
|
||||
}
|
||||
|
||||
public LinkNode(String[] keyStrings, int pos, FilterNodeBean node) {
|
||||
this.key = keyStrings[pos];
|
||||
this.or = this.key.contains("[OR]");
|
||||
put(keyStrings, pos, node);
|
||||
}
|
||||
|
||||
public FilterNodeBean createFilterNodeBean() {
|
||||
FilterNodeBean node = null;
|
||||
for (FilterNodeBean bean : beans) {
|
||||
node = node == null ? bean : node.any(bean, or);
|
||||
}
|
||||
for (LinkNode link : nexts.values()) {
|
||||
FilterNodeBean f = link.createFilterNodeBean();
|
||||
if (f == null) continue;
|
||||
node = node == null ? f : node.any(f, or);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public final void put(final String[] keys, int pos, final FilterNodeBean node) {
|
||||
if (keys.length == pos + 1 && this.key.equals(keys[pos])) {
|
||||
this.beans.add(node);
|
||||
return;
|
||||
}
|
||||
LinkNode link = nexts.get(keys[pos + 1]);
|
||||
if (link == null) {
|
||||
nexts.put(keys[pos + 1], new LinkNode(keys, pos + 1, node));
|
||||
} else {
|
||||
link.put(keys, pos + 1, node);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{key = '").append(key).append("', or = ").append(or);
|
||||
if (!beans.isEmpty()) {
|
||||
sb.append(", beans = [\r\n");
|
||||
for (FilterNodeBean bean : this.beans) {
|
||||
sb.append(" ").append(bean).append("\r\n");
|
||||
}
|
||||
sb.append("]");
|
||||
}
|
||||
if (!nexts.isEmpty()) {
|
||||
sb.append(", nexts = [\r\n");
|
||||
for (LinkNode link : this.nexts.values()) {
|
||||
sb.append(" ").append(link).append("\r\n");
|
||||
}
|
||||
sb.append("]");
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static FilterNodeBean load(Class<? extends FilterBean> clazz) {
|
||||
FilterNodeBean rs = beanodes.get(clazz);
|
||||
if (rs != null) return rs;
|
||||
synchronized (beanodes) {
|
||||
rs = beanodes.get(clazz);
|
||||
if (rs == null) {
|
||||
rs = createFilterNodeBean(clazz);
|
||||
beanodes.put(clazz, rs);
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(joinClass == null ? null : joinClass.getSimpleName()).toString();
|
||||
}
|
||||
|
||||
protected StringBuilder toString(final String prefix) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuilder element = toElementString(prefix);
|
||||
boolean more = element.length() > 0 && this.nodeBeans != null;
|
||||
if (more) sb.append('(');
|
||||
sb.append(element);
|
||||
if (this.nodeBeans != null) {
|
||||
for (FilterNodeBean node : this.nodeBeans) {
|
||||
String s = node.toString();
|
||||
if (s.length() < 1) continue;
|
||||
if (sb.length() > 1) sb.append(or ? " OR " : " AND ");
|
||||
sb.append(s);
|
||||
}
|
||||
}
|
||||
if (more) sb.append(')');
|
||||
return sb;
|
||||
}
|
||||
|
||||
protected final StringBuilder toElementString(final String prefix) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (column != null) {
|
||||
String col = prefix == null ? column : (prefix + "." + column);
|
||||
if (express == ISNULL || express == ISNOTNULL) {
|
||||
sb.append(col).append(' ').append(express.value());
|
||||
} else {
|
||||
sb.append((express == IGNORECASELIKE || express == IGNORECASENOTLIKE) ? ("LOWER(" + col + ')') : col).append(' ').append(express.value()).append(" ?");
|
||||
}
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user