ars.database.repository.StandardTransferManager Maven / Gradle / Ivy
package ars.database.repository;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.ArrayList;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.MethodInterceptor;
import ars.util.Beans;
import ars.util.Strings;
import ars.util.Conditions;
import ars.util.Conditions.Or;
import ars.util.Conditions.And;
import ars.util.Conditions.Logic;
import ars.util.Conditions.Condition;
import ars.invoke.request.Requester;
import ars.database.repository.Query;
import ars.database.repository.Transform;
import ars.database.repository.EmptyQuery;
import ars.database.repository.Repositories;
import ars.database.repository.TransferManager;
import ars.database.repository.DataConstraintException;
/**
* 数据转换管理接口标准实现
*
* @author yongqiangwu
*
*/
public class StandardTransferManager implements TransferManager {
private Map, Map> mappings = new HashMap, Map>();
@Override
public boolean isRegistered(Class> model, String property) {
Map transforms = this.mappings.get(model);
return transforms != null && transforms.containsKey(property);
}
@Override
public void register(Class> model, String property, Transform transform) {
if (model == null) {
throw new IllegalArgumentException("Illegal model:" + model);
}
if (property == null) {
throw new IllegalArgumentException("Illegal property:" + property);
}
if (transform == null) {
throw new IllegalArgumentException("Illegal transform:" + transform);
}
Map transforms = this.mappings.get(model);
if (transforms == null) {
transforms = new HashMap();
this.mappings.put(model, transforms);
}
if (transforms.containsKey(property)) {
throw new RuntimeException("Transform is already registered:" + model.getName() + "." + property);
}
transforms.put(property, transform);
}
@Override
public void register(Class> model, Map transforms) {
for (Entry entry : transforms.entrySet()) {
this.register(model, entry.getKey(), entry.getValue());
}
}
@Override
public Query getTransferQuery(Requester requester, Query query) {
return new TransferQuery(requester, query);
}
/**
* 数据转换执行对象
*
* @author yongqiangwu
*
*/
class TransferExecutor {
private Transform transform; // 转换条件对象
private String property; // 目标属性名称
public TransferExecutor(Transform transform, String property) {
if (transform == null) {
throw new IllegalArgumentException("Illegal transform:" + transform);
}
if (property == null) {
throw new IllegalArgumentException("Illegal property:" + property);
}
this.transform = transform;
this.property = property;
}
public Transform getTransform() {
return transform;
}
public String getProperty() {
return property;
}
/**
* 数据转换调用
*
* @param requester
* 请求对象
* @param handle
* 匹配模式
* @param value
* 匹配值
* @return 调用结果(对象数组)
*/
public Object[] invoke(Requester requester, String handle, Object value) {
StringBuilder key = new StringBuilder(this.property);
if (!Strings.isEmpty(handle)) {
key.append(Query.DELIMITER).append(handle);
}
Map parameters = new HashMap(1);
parameters.put(key.toString(), value);
Object object = requester.execute(this.transform.getResource(), parameters);
if (object instanceof RuntimeException) {
throw (RuntimeException) object;
} else if (object instanceof Exception) {
throw new RuntimeException((Exception) object);
}
List> targets = (List>) Beans.getAssemblePropertyValue(object, this.transform.getKey());
return targets == null || targets.isEmpty() ? Beans.EMPTY_ARRAY : targets.toArray();
}
}
/**
* 获取数据查询转换对象
*
* @param model
* 数据模型
* @param property
* 查询属性名称
* @return 数据查询转换对象
*/
protected TransferExecutor getTransferExecutor(Class> model, String property) {
int split = property.indexOf('.');
String direct = split > 0 ? property.substring(0, split) : property;
Map transforms = this.mappings.get(model);
Transform transform = transforms == null ? null : transforms.get(direct);
return transform == null ? null
: new TransferExecutor(transform, split > 0 ? property.substring(split + 1) : transform.getKey());
}
/**
* 数据转换查询对象
*
* @author yongqiangwu
*
* @param
* 数据模型
*/
class TransferQuery implements Query {
private T object; // 单个实例
private List objects; // 实例列表
private boolean loaded; // 数据是否已加载
private Query query; // 数据查询对象
private Requester requester; // 请求对象
public TransferQuery(Requester requester, Query query) {
if (query == null) {
throw new IllegalArgumentException("Illegal query:" + query);
}
if (requester == null) {
throw new IllegalArgumentException("Illegal requester:" + requester);
}
this.query = query;
this.requester = requester;
}
/**
* 实体转换属性数据加载
*
* @param entity
* 对象实体
* @param transforms
* 属性名称/数据转换对象映射
* @return 加载完成后的对象实体
*/
@SuppressWarnings("unchecked")
protected T load(T entity, Map transforms) {
final Map lazies = new HashMap(transforms.size());
for (Entry entry : transforms.entrySet()) {
String property = entry.getKey();
Transform transform = entry.getValue();
Object value = Beans.getValue(entity, transform.getTarget());
if (value != null) {
if (transform.isLazy()) {
lazies.put(property, transform);
continue;
}
Beans.setValue(entity, property, this.transfer(property, value, transform));
}
}
if (lazies.isEmpty()) {
return entity;
}
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.getModel());
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy)
throws Throwable {
String name = method.getName();
Object value = proxy.invokeSuper(target, args);
if (value != null || !name.startsWith("get")) {
return value;
}
String property = name.substring(3).toLowerCase();
Transform transform = lazies.get(property);
if (transform == null) {
return value;
}
Object transfer = transfer(property, Beans.getValue(target, transform.getTarget()), transform);
Beans.setValue(target, property, transfer);
return transfer;
}
});
T proxy = (T) enhancer.create();
Beans.copy(entity, proxy);
return proxy;
}
/**
* 条件逻辑对象转换
*
* @param logic
* 条件逻辑对象
* @return 条件逻辑对象
*/
protected Logic transfer(Logic logic) {
if (logic == null) {
return null;
} else if (logic instanceof Or) {
Logic[] logics = ((Or) logic).getLogics();
for (int i = 0; i < logics.length; i++) {
logics[i] = this.transfer(logics[i]);
}
return logic;
} else if (logic instanceof And) {
Logic[] logics = ((And) logic).getLogics();
for (int i = 0; i < logics.length; i++) {
Logic transfer = this.transfer(logics[i]);
if (transfer == null) {
return null;
}
logics[i] = transfer;
}
return logic;
} else if (logic instanceof Condition) {
Condition condition = (Condition) logic;
String property = condition.getKey();
Object value = condition.getValue();
String handle = EQ;
int index = property.indexOf(DELIMITER);
if (index > 0) {
handle = property.substring(index + DELIMITER.length());
property = property.substring(0, index);
}
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor == null) {
return logic;
}
Object[] targets = executor.invoke(this.requester, handle, value);
if (targets == null || targets.length == 0) {
return null;
}
String key = new StringBuilder(executor.getTransform().getTarget()).append(DELIMITER).append(IN)
.toString();
return new Condition(key, targets);
}
throw new RuntimeException("Not support query logic:" + logic);
}
/**
* 数据转化
*
* @param property
* 属性名称
* @param value
* 属性值
* @param transform
* 数据转换对象
* @return 转换后数据对象
*/
protected Object transfer(String property, Object value, Transform transform) {
Class> targetClass = Beans.getField(this.getModel(), property).getType();
Map parameters = new HashMap(1);
parameters.put(transform.getKey(), value);
Object result = this.requester.execute(transform.getResource(), parameters);
if (result instanceof RuntimeException) {
throw (RuntimeException) result;
} else if (result instanceof Exception) {
throw new RuntimeException((Exception) result);
}
List> targets = (List>) result;
if (targets == null || targets.isEmpty()) {
throw new DataConstraintException("Object does not exist:" + targetClass.getName() + parameters);
}
return Beans.initialize(targetClass, (Map, ?>) targets.get(0));
}
/**
* 执行数据数据转换查询
*
* @param executor
* 数据查询转换对象
* @param handle
* 匹配模式
* @param value
* 匹配值
* @return 数据查询对象
*/
protected Query execute(TransferExecutor executor, String handle, Object value) {
Object[] targets = executor.invoke(this.requester, handle, value);
if (targets == null || targets.length == 0) {
return Repositories.emptyQuery();
}
this.query.in(executor.getTransform().getTarget(), targets);
return this;
}
@Override
public Iterator iterator() {
return this.list().iterator();
}
@Override
public Class getModel() {
return this.query.getModel();
}
@Override
public Query empty(String... properties) {
if (properties != null && properties.length > 0) {
for (String property : properties) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor == null) {
this.query.empty(property);
continue;
} else if (executor.getProperty().equals(executor.getTransform().getTarget())) {
this.query.empty(executor.getProperty());
continue;
}
return this.execute(executor, EMPTY, null);
}
}
return this;
}
@Override
public Query nonempty(String... properties) {
if (properties != null && properties.length > 0) {
for (String property : properties) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor == null) {
this.query.nonempty(property);
continue;
} else if (executor.getProperty().equals(executor.getTransform().getTarget())) {
this.query.nonempty(executor.getProperty());
continue;
}
return this.execute(executor, NOT_EMPTY, null);
}
}
return this;
}
@Override
public Query eq(String property, Object value) {
if (property != null && value != null) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, EQ, value);
}
this.query.eq(property, value);
}
return this;
}
@Override
public Query ne(String property, Object value) {
if (property != null && value != null) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, NE, value);
}
this.query.ne(property, value);
}
return this;
}
@Override
public Query gt(String property, Object value) {
if (property != null && value != null) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, GT, value);
}
this.query.gt(property, value);
}
return this;
}
@Override
public Query ge(String property, Object value) {
if (property != null && value != null) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, GE, value);
}
this.query.ge(property, value);
}
return this;
}
@Override
public Query lt(String property, Object value) {
if (property != null && value != null) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, LT, value);
}
this.query.lt(property, value);
}
return this;
}
@Override
public Query le(String property, Object value) {
if (property != null && value != null) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, LE, value);
}
this.query.le(property, value);
}
return this;
}
@Override
public Query between(String property, Object low, Object high) {
if (property != null && low != null && high != null) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, IN, new Object[] { low, high });
}
this.query.between(property, low, high);
}
return this;
}
@Override
public Query start(String property, String... values) {
if (property != null && values != null && values.length > 0) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, START, values);
}
this.query.start(property, values);
}
return this;
}
@Override
public Query nstart(String property, String... values) {
if (property != null && values != null && values.length > 0) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, NOT_START, values);
}
this.query.nstart(property, values);
}
return this;
}
@Override
public Query end(String property, String... values) {
if (property != null && values != null && values.length > 0) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, END, values);
}
this.query.end(property, values);
}
return this;
}
@Override
public Query nend(String property, String... values) {
if (property != null && values != null && values.length > 0) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, NOT_END, values);
}
this.query.nend(property, values);
}
return this;
}
@Override
public Query like(String property, String... values) {
if (property != null && values != null && values.length > 0) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, LIKE, values);
}
this.query.like(property, values);
}
return this;
}
@Override
public Query nlike(String property, String... values) {
if (property != null && values != null && values.length > 0) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, NOT_LIKE, values);
}
this.query.nlike(property, values);
}
return this;
}
@Override
public Query in(String property, Object[] values) {
if (property != null && values != null && values.length > 0) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, IN, values);
}
this.query.in(property, values);
}
return this;
}
@Override
public Query or(String property, Object[] values) {
if (property != null && values != null && values.length > 0) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, OR, values);
}
this.query.or(property, values);
}
return this;
}
@Override
public Query not(String property, Object[] values) {
if (property != null && values != null && values.length > 0) {
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, NOT, values);
}
this.query.not(property, values);
}
return this;
}
@Override
public Query custom(String property, Object value) {
if (Strings.isEmpty(property) || property.equals(PAGE) || property.equals(SIZE) || property.equals(ORDER)) {
this.query.custom(property, value);
return this;
} else if (property.equals(CONDITION)) {
if (!Beans.isEmpty(value)) {
Logic logic = value instanceof Logic ? (Logic) value : Conditions.parse(value.toString());
return this.condition(logic);
}
return this;
}
return this.condition(property, value);
}
@Override
public Query custom(Map parameters) {
if (parameters != null && !parameters.isEmpty()) {
for (Entry entry : parameters.entrySet()) {
Query query = this.custom(entry.getKey(), entry.getValue());
if (query instanceof EmptyQuery) {
return query;
}
}
}
return this;
}
@Override
public Query condition(Logic logic) {
if (logic != null) {
Logic transfer = this.transfer(logic);
if (transfer == null) {
return Repositories.emptyQuery();
}
this.query.condition(transfer);
}
return this;
}
@Override
public Query condition(String property, Object value) {
String handle = EQ;
int index = property.indexOf(DELIMITER);
if (index > 0) {
handle = property.substring(index + DELIMITER.length());
property = property.substring(0, index);
}
TransferExecutor executor = getTransferExecutor(this.getModel(), property);
if (executor != null) {
return this.execute(executor, handle, value);
}
this.query.custom(property, value);
return this;
}
@Override
public Query condition(Map parameters) {
if (parameters != null && !parameters.isEmpty()) {
for (Entry entry : parameters.entrySet()) {
Query query = this.condition(entry.getKey(), entry.getValue());
if (query instanceof EmptyQuery) {
return query;
}
}
}
return this;
}
@Override
public Query eqProperty(String property, String other) {
this.query.eqProperty(property, other);
return this;
}
@Override
public Query neProperty(String property, String other) {
this.query.neProperty(property, other);
return this;
}
@Override
public Query ltProperty(String property, String other) {
this.query.ltProperty(property, other);
return this;
}
@Override
public Query leProperty(String property, String other) {
this.query.leProperty(property, other);
return this;
}
@Override
public Query gtProperty(String property, String other) {
this.query.gtProperty(property, other);
return this;
}
@Override
public Query geProperty(String property, String other) {
this.query.geProperty(property, other);
return this;
}
@Override
public Query asc(String... properties) {
this.query.asc(properties);
return this;
}
@Override
public Query desc(String... properties) {
this.query.desc(properties);
return this;
}
@Override
public Query paging(int page, int size) {
this.query.paging(page, size);
return this;
}
@Override
public Query min(String... properties) {
this.query.min(properties);
return this;
}
@Override
public Query max(String... properties) {
this.query.max(properties);
return this;
}
@Override
public Query avg(String... properties) {
this.query.avg(properties);
return this;
}
@Override
public Query sum(String... properties) {
this.query.sum(properties);
return this;
}
@Override
public Query number(String... properties) {
this.query.number(properties);
return this;
}
@Override
public Query group(String... properties) {
this.query.group(properties);
return this;
}
@Override
public Query property(String... properties) {
this.query.property(properties);
return this;
}
@Override
public int count() {
return this.query.count();
}
@Override
public T single() {
if (!this.loaded) {
this.loaded = true;
this.object = this.query.single();
Map transforms = mappings.get(this.getModel());
if (transforms != null) {
this.object = this.load(this.object, transforms);
}
}
return this.object;
}
@Override
public List list() {
if (!this.loaded) {
this.loaded = true;
this.objects = this.query.list();
Map transforms = mappings.get(this.getModel());
if (transforms != null) {
List loads = new ArrayList(this.objects.size());
for (int i = 0; i < this.objects.size(); i++) {
loads.add(this.load(this.objects.get(i), transforms));
}
this.objects = loads;
}
}
return this.objects;
}
@Override
public List> stats() {
return this.query.stats();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy