use of io.github.ihongs.dh.MergeMore in project HongsCORE by ihongs.
the class SelectHelper method injectFork.
public void injectFork(List<Map> list, byte ad) {
if (forks.isEmpty())
return;
ActionHelper ah = ActionHelper.newInstance();
MergeMore mm = new MergeMore(list);
Map cd = new HashMap();
Map rd = new HashMap();
Set ab = new HashSet();
Set rb = new HashSet();
// 子级 rb
Map<String, Set> sb = new HashMap();
// 子级 ob
Map<String, Set> ob = new HashMap();
ah.setContextData(cd);
ah.setRequestData(rd);
// 传递 ab 参数
if (TEXT == (TEXT & ad)) {
ab.add("_text");
}
if (TIME == (TIME & ad)) {
ab.add("_time");
}
if (LINK == (LINK & ad)) {
ab.add("_link");
}
if (FORK == (FORK & ad)) {
ab.add("_fork");
}
// 预先提取所有下级
Set ts = new HashSet();
for (Map.Entry et : forks.entrySet()) {
Map mt = (Map) et.getValue();
String fn = (String) et.getKey();
// 关联外键
String fk = (String) mt.get("data-fk");
// 数据放入此下
String ak = (String) mt.get("data-ak");
if (ak == null || ak.isEmpty()) {
if (fk == null || fk.isEmpty()) {
if (fn.endsWith("_id")) {
int ln = fn.length() - 3;
ak = fn.substring(0, ln);
} else {
ak = fn + "_fork";
}
} else {
ak = fn;
}
}
ts.add(ak);
}
// 子级 rb 参数
if (_cols != null) {
String t, f;
for (Object o : _cols) {
f = Synt.asString(o);
int p = f.indexOf(".");
if (p != -1) {
t = f.substring(0, p);
f = f.substring(1 + p);
if (!ts.contains(t))
continue;
Set nb = sb.get(t);
if (nb == null) {
nb = new LinkedHashSet();
sb.put(t, nb);
}
nb.add(f);
}
}
}
// 子级 ob 参数
if (_ords != null) {
String t, f;
for (Object o : _ords) {
f = Synt.asString(o);
int p = f.indexOf(".");
if (p != -1) {
t = f.substring(0, p);
f = f.substring(1 + p);
if (!ts.contains(t))
continue;
Set nb = ob.get(t);
if (nb == null) {
nb = new LinkedHashSet();
ob.put(t, nb);
}
nb.add(f);
}
}
}
for (Map.Entry et : forks.entrySet()) {
Map mt = (Map) et.getValue();
String fn = (String) et.getKey();
// 关联外键
String fk = (String) mt.get("data-fk");
// 建立映射, 清除空值可避免不必要的查询
Map<Object, List> ms = mm.mapped(fk != null ? fk : fn);
ms.remove("");
ms.remove(null);
if (ms.isEmpty()) {
continue;
}
// 关联动作路径
String at = (String) mt.get("data-at");
// 数据放入此下
String ak = (String) mt.get("data-ak");
// 关联字段
String vk = (String) mt.get("data-vk");
// 名称字段
String tk = (String) mt.get("data-tk");
if (at == null || at.isEmpty()) {
String c = (String) mt.get("conf");
String f = (String) mt.get("form");
at = c + "/" + f + "/search";
}
if (ak == null || ak.isEmpty()) {
if (fk == null || fk.isEmpty()) {
if (fn.endsWith("_id")) {
int ln = fn.length() - 3;
ak = fn.substring(0, ln);
} else {
ak = fn + "_fork";
}
} else {
ak = fn;
}
}
if (vk == null || vk.isEmpty()) {
vk = Cnst.ID_KEY;
}
if (tk == null || tk.isEmpty()) {
tk = "name";
}
rd.clear();
rb.clear();
rb.add(vk);
rb.add(tk);
// 附加参数
int ps = at.indexOf('?');
if (ps > -1) {
String aq;
aq = at.substring(1 + ps).trim();
at = at.substring(0, ps).trim();
if (aq.startsWith("{") && aq.endsWith("}")) {
rd.putAll((Map) Dawn.toObject(aq));
} else {
rd.putAll(ActionHelper.parseQuery(aq));
}
}
// 关联参数
rd.put(vk, ms.keySet());
rd.put(Cnst.RN_KEY, 0);
Set xb;
xb = Synt.toTerms(rd.get(Cnst.AB_KEY));
if (xb == null) {
xb = ab;
}
rd.put(Cnst.AB_KEY, xb);
xb = Synt.toTerms(rd.get(Cnst.RB_KEY));
if (xb == null) {
xb = rb;
}
rd.put(Cnst.RB_KEY, xb);
// 请求参数
Map rq = Synt.toMap(mt.get("data-rd"));
if (rq != null && !rq.isEmpty()) {
rd.putAll(rq);
}
// 查询字段
// 若内部有许可的且外部有指定的
// 则取二者的交集作为查询的字段
Set rp = Synt.toSet(mt.get("data-rb"));
if (rp != null && !rp.isEmpty()) {
Set nb = sb.get(ak);
if (nb != null) {
nb.retainAll(rp);
if (!nb.isEmpty())
rd.put(Cnst.RB_KEY, nb);
}
}
// 排序字段
// 若内部有许可的且外部有指定的
// 则取二者的交集作为排序的字段
Set op = Synt.toSet(mt.get("data-ob"));
if (op != null && !op.isEmpty()) {
Set nb = ob.get(ak);
if (nb != null) {
nb.retainAll(op);
if (!nb.isEmpty())
rd.put(Cnst.OB_KEY, nb);
}
}
// 没有 ab 就没必要调用注解过滤
try {
ActionRunner ar = ActionRunner.newInstance(ah, at);
if (xb.isEmpty()) {
ar.doInvoke();
} else {
ar.doAction();
}
} catch (HongsException e) {
throw e.toExemption();
}
// 整合数据
Map sd = ah.getResponseData();
List<Map> ls = (List) sd.get("list");
if (ls == null) {
continue;
}
if (Synt.declare(mt.get("__repeated__"), false)) {
// 预置数据
for (Map.Entry<Object, List> lr : ms.entrySet()) {
List<Map> lst = lr.getValue();
for (Map row : lst) {
row.put(ak, new ArrayList());
}
}
mm.append(ls, ms, vk, ak);
} else {
// 预置数据
for (Map.Entry<Object, List> lr : ms.entrySet()) {
List<Map> lst = lr.getValue();
for (Map row : lst) {
row.put(ak, new HashMap());
}
}
mm.extend(ls, ms, vk, ak);
}
}
}
use of io.github.ihongs.dh.MergeMore in project HongsCORE by ihongs.
the class MoreAction method more.
private void more(ActionHelper helper, String sub, HttpServletRequest req, HttpServletResponse rsp, Map re0, Map rs0, MergeMore meg, int l) {
String uri;
String key;
String col;
Map re1;
Map rs1;
try {
uri = (String) re0.remove("at");
key = (String) re0.remove("on");
re1 = (Map) re0.remove("in");
} catch (ClassCastException e) {
return;
}
if (uri != null) {
if (meg != null) {
if (key != null) {
int p = key.indexOf('=');
if (p >= 0) {
col = key.substring(1 + p);
key = key.substring(0, p);
} else {
col = Cnst.ID_KEY;
}
} else {
col = Cnst.ID_KEY;
key = sub + "_" + Cnst.ID_KEY;
}
// 映射参数
Map<Object, List> map;
map = meg.mapped(key);
if (map.isEmpty()) {
return;
}
// 请求参数
if (re1 == null) {
re1 = new HashMap();
}
re1.put(col, map.keySet());
// 执行请求
helper.reply((Map) null);
helper.setRequestData(re1);
eval(helper, uri, req, rsp);
rs1 = helper.getResponseData();
if (rs1 == null) {
return;
}
// 获取列表
List<Map> list = (List) rs1.get("list");
if (list == null) {
Map info = (Map) rs1.get("info");
if (info != null) {
list = Synt.listOf(info);
} else {
return;
}
}
// 预设关联
for (Map.Entry<Object, List> lr : map.entrySet()) {
List<Map> lst = lr.getValue();
for (Map row : lst) {
row.put(sub, new ArrayList());
}
}
// 执行关联
meg.append(list, map, col, sub);
// 下级关联
meg = new MergeMore(list);
} else {
// 请求参数
if (re1 == null) {
re1 = new HashMap();
}
// 执行请求
helper.reply((Map) null);
helper.setRequestData(re1);
eval(helper, uri, req, rsp);
rs1 = helper.getResponseData();
// 响应数据
if (rs1 == null) {
return;
}
if (sub == null) {
rs0.putAll(rs1);
} else {
rs0.put(sub, rs1);
// 首个错误上移
if (Synt.declare(rs0.get("ok"), true) && !Synt.declare(rs1.get("ok"), true)) {
rs0.put("ok", false);
if (rs1.containsKey("ern")) {
rs0.put("ern", rs1.get("ern"));
}
if (rs1.containsKey("err")) {
rs0.put("err", rs1.get("err"));
}
if (rs1.containsKey("msg")) {
rs0.put("msg", rs1.get("msg"));
}
}
}
// 获取列表
List<Map> list = (List) rs1.get("list");
if (list == null) {
Map info = (Map) rs1.get("info");
if (info != null) {
list = Synt.listOf(info);
} else {
return;
}
}
// 下级关联
meg = new MergeMore(list);
}
} else if (l == 0) {
rs1 = rs0;
} else {
return;
}
/* 下级数据 */
l++;
for (Object ot : re0.entrySet()) {
Map.Entry et = (Map.Entry) ot;
Object k = et.getKey();
Object v = et.getValue();
if (v instanceof Map && k instanceof String) {
re1 = (Map) v;
sub = (String) k;
more(helper, sub, req, rsp, re1, rs1, meg, l);
}
}
}
Aggregations