cn.k7g.alloy.mold.impl.AbstractMoldService Maven / Gradle / Ivy
package cn.k7g.alloy.mold.impl;
import cn.k7g.alloy.annotation.MoldMethod;
import cn.k7g.alloy.annotation.MoldObject;
import cn.k7g.alloy.expose.DataProvider;
import cn.k7g.alloy.mold.BaseMold;
import cn.k7g.alloy.mold.MoldConfig;
import cn.k7g.alloy.mold.MoldService;
import cn.k7g.alloy.mold.var.AbsVar;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.NoSuchMessageException;
import org.springframework.expression.AccessException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.support.ReflectiveMethodExecutor;
import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* AbstractMoldService
* @date 2021/2/5 下午1:46
* @author victor-wu
*/
public abstract class AbstractMoldService implements MoldService {
@Autowired
protected ApplicationContext context;
@Autowired
protected MoldConfig moldConfig;
final Map> globalMethod = new HashMap>() {
@Override
public List get(Object key) {
List ret = super.get(key);
if (ret == null) {
ret = new ArrayList<>();
super.put(key.toString(), ret);
}
return ret;
}
};
final Map globalObject = new HashMap<>();
@PostConstruct
public void init() {
Map mos = context.getBeansWithAnnotation(MoldObject.class);
for (Map.Entry item : mos.entrySet()) {
MoldObject moldObject = item.getValue().getClass().getAnnotation(MoldObject.class);
for (MoldObject.Scope scope : moldObject.scope()) {
if (scope == MoldObject.Scope.OBJECT) {
String name = moldObject.value();
if (name.isEmpty()) {
name = item.getValue().getClass().getSimpleName();
}
globalObject.put(name, item.getValue());
}
if (scope == MoldObject.Scope.METHOD) {
Method[] methods = item.getValue().getClass().getMethods();
for (Method method : methods) {
MoldMethod moldMethod = method.getAnnotation(MoldMethod.class);
if (moldMethod == null || moldMethod.ignore()) {
continue;
}
globalMethod.get(method.getName()).add(new DelegateMethod(item.getValue(), method));
}
}
}
}
}
/**
* 准备可以用的变量
* @param baseMold
* @return
*/
public GlobalVal readyVar(BaseMold baseMold) {
GlobalVal params = new GlobalVal();
Set> entries = baseMold.getModel().entrySet();
Map beansOfType = context.getBeansOfType(DataProvider.class);
for (Map.Entry entry : entries) {
DataProvider provider = beansOfType.entrySet().stream()
.filter(o -> o.getValue().supports(entry.getValue()))
.limit(1)
.findFirst()
.orElseThrow(() -> new NoSuchMessageException("没有找到支持 " + entry.getValue().getClass().getName() + "的 DataProvider, 是否忘记声明为 spring component了"))
.getValue();
params.put(entry.getKey(), provider.get(entry.getValue()));
params.put("_" + entry.getKey(), entry.getValue());
}
params.putAll(moldConfig.getEnvVar());
params.putAll(globalObject);
return params;
}
static class GlobalVal extends HashMap {
}
@AllArgsConstructor
static class DelegateMethod {
public Object target;
public Method originMethod;
}
static class DelegateExecutor extends ReflectiveMethodExecutor {
private DelegateMethod dm;
public DelegateExecutor(DelegateMethod dm) {
super(dm.originMethod);
this.dm = dm;
}
@Override
public TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException {
return super.execute(context, this.dm.target, arguments);
}
}
}