silentbalanceyh/vertx-zero

View on GitHub
vertx-pin/zero-ui/src/main/java/cn/vertxup/ui/service/ControlService.java

Summary

Maintainability
A
1 hr
Test Coverage
package cn.vertxup.ui.service;

import cn.vertxup.ui.domain.tables.daos.UiControlDao;
import cn.vertxup.ui.domain.tables.daos.UiVisitorDao;
import cn.vertxup.ui.domain.tables.pojos.UiControl;
import cn.vertxup.ui.domain.tables.pojos.UiVisitor;
import io.horizon.spi.ui.UiHunter;
import io.horizon.uca.log.Annal;
import io.vertx.core.Future;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.mod.ui.cv.em.ControlType;
import io.vertx.up.atom.typed.UData;
import io.vertx.up.eon.KName;
import io.vertx.up.fn.Fn;
import io.vertx.up.unity.Ux;
import io.vertx.up.util.Ut;

import java.util.Objects;

import static io.vertx.mod.ui.refine.Ui.LOG;

public class ControlService implements ControlStub {

    private static final Annal LOGGER = Annal.get(ControlService.class);

    @Override
    public Future<JsonArray> fetchControls(final String pageId) {
        return Ux.Jooq.on(UiControlDao.class)
            .<UiControl>fetchAsync("pageId", pageId)
            .compose(Ux::futureA)
            .compose(list -> {
                /*
                 * Convert JsonArray field of Control
                 */
                final JsonArray result = new JsonArray();
                list.stream().filter(Objects::nonNull)
                    .map(item -> (JsonObject) item)
                    .map(item -> Ut.valueToJObject(item,
                        KName.Ui.CONTAINER_CONFIG,
                        KName.Ui.COMPONENT_CONFIG,
                        KName.Ui.ASSIST,
                        KName.Ui.GRID
                    ))
                    .forEach(result::add);
                return Ux.future(result);
            });
    }

    @Override
    public Future<JsonObject> fetchById(final String control) {
        return Ux.Jooq.on(UiControlDao.class)
            .<UiControl>fetchByIdAsync(control)
            .compose(Ux::futureJ)
            .compose(Fn.ofJObject(
                KName.Ui.CONTAINER_CONFIG,
                KName.Ui.COMPONENT_CONFIG,
                KName.Ui.ASSIST,
                KName.Ui.GRID
            ));
    }

    @Override
    public Future<JsonObject> fetchControl(final ControlType controlType, final JsonObject params) {
        /*
         * The first step to fetch UI_VISITOR record.
         * {
         *      "type": "组件类型:LIST | FORM",
         *      "sigma": "统一标识符",
         *      "page": "页面ID,对应 UI_PAGE 中的记录",
         *      "path": "三部分组成,前端自动计算的 view / position,配置中的 __ALIAS__ -> alias",
         *      "identifier": "建模管理中模型专用标识符 identifier"
         * }
         */
        final JsonObject criteria = Ux.whereAnd();
        criteria.put(KName.TYPE, controlType.name());
        Ut.valueCopy(criteria, params,
            KName.SIGMA,
            KName.IDENTIFIER,
            KName.Ui.PAGE,
            KName.App.PATH
        );
        LOG.Ui.info(LOGGER, "Control ( type = {0} ) with parameters = `{1}`", controlType, criteria.encode());
        return Ux.Jooq.on(UiVisitorDao.class).<UiVisitor>fetchOneAsync(criteria).compose(visitor -> {
            if (Objects.isNull(visitor)) {
                /* 「空」无任何记录,直接返回空结果 */
                return Ux.futureJ();
            }
            if (Ut.isNil(visitor.getControlId())) {
                /* 不包含 controlId,如果不包含,则执行第二级操作 */
                final String component = visitor.getRunComponent();
                if (Ut.isNil(component)) {
                    /* 「空」组件未配置,返回空结果 */
                    return Ux.futureJ();
                }
                final Class<?> clazz = Ut.clazz(component, null);
                /*
                 * 两个规范
                 * 1. 「空」clazz 为空,跳出
                 * 2. 「实现」clazz 必须实现了 UiHunter.class 接口
                 */
                if (Objects.isNull(clazz) || !Ut.isImplement(clazz, UiHunter.class)) {
                    /* 「空」组件规范不合法,返回空结果 */
                    return Ux.futureJ();
                }
                /* 再次检索,构造 UData */
                final UiHunter hunter = Ut.instance(clazz);
                final UData data = UData.createJ(params);
                return hunter.seek(data, visitor).compose(controlId -> {
                    final JsonObject response = Ux.toJson(visitor);
                    response.put(KName.Ui.CONTROL_ID, controlId);
                    return Ux.future(response);
                });
            } else {
                /* 包含 controlId,直接执行返回,最终返回数据必须包含 controlId */
                return Ux.futureJ(visitor);
            }
        });
    }
}