Skip to content

Commit

Permalink
生成业务规则输入数据所对应的json schema
Browse files Browse the repository at this point in the history
  • Loading branch information
entropy-cloud committed Sep 3, 2023
1 parent bbe822a commit 3104b89
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import io.nop.api.core.annotations.biz.BizAction;
import io.nop.api.core.annotations.biz.BizModel;
import io.nop.api.core.annotations.biz.BizQuery;
import io.nop.api.core.annotations.biz.RequestBean;
import io.nop.api.core.annotations.core.Name;
import io.nop.api.core.beans.DictBean;
import io.nop.api.core.beans.DictOptionBean;
import io.nop.api.core.beans.WebContentBean;
import io.nop.biz.crud.CrudBizModel;
import io.nop.biz.crud.EntityData;
import io.nop.commons.util.StringHelper;
Expand All @@ -15,13 +17,16 @@
import io.nop.file.core.FileConstants;
import io.nop.orm.IOrmEntityFileStore;
import io.nop.orm.OrmConstants;
import io.nop.rule.api.beans.RuleKeyBean;
import io.nop.rule.core.excel.RuleExcelModelParser;
import io.nop.rule.core.model.RuleModel;
import io.nop.rule.dao.entity.NopRuleDefinition;
import io.nop.rule.dao.model.DaoRuleModelLoader;
import io.nop.rule.dao.model.DaoRuleModelSaver;
import io.nop.rule.service.NopRuleConstants;
import io.nop.web.page.condition.ConditionSchemaHelper;
import io.nop.xlang.xmeta.ISchema;
import io.nop.xlang.xmeta.jsonschema.XSchemaToJsonSchema;

import javax.inject.Inject;
import java.util.List;
Expand Down Expand Up @@ -71,6 +76,14 @@ public DictBean getOutputFields(@Name(NopRuleConstants.RULE_ID_NAME) String rule
return dict;
}

@BizQuery
public WebContentBean getInputJsonSchema(@RequestBean RuleKeyBean ruleKey, IServiceContext context) {
NopRuleDefinition rule = ruleModelLoader.loadRuleDefinition(ruleKey.getRuleName(), ruleKey.getRuleVersion());
ISchema schema = ruleModelLoader.buildRuleInputSchema(rule);
Map<String, Object> jsonSchema = XSchemaToJsonSchema.instance().toJsonSchema(schema, context);
return WebContentBean.json(jsonSchema);
}

@Override
@BizAction
protected void defaultPrepareSave(EntityData<NopRuleDefinition> entityData, IServiceContext context) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package io.nop.xlang.xmeta.jsonschema;

import io.nop.api.core.beans.DictBean;
import io.nop.api.core.context.ContextProvider;
import io.nop.commons.type.StdDataType;
import io.nop.core.context.IServiceContext;
import io.nop.core.dict.DictProvider;
import io.nop.xlang.xmeta.IObjPropMeta;
import io.nop.xlang.xmeta.IObjSchema;
import io.nop.xlang.xmeta.ISchema;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class XSchemaToJsonSchema {
static XSchemaToJsonSchema _instance = new XSchemaToJsonSchema();

public static void registerInstance(XSchemaToJsonSchema instance) {
_instance = instance;
}

public static XSchemaToJsonSchema instance() {
return _instance;
}

public Map<String, Object> toJsonSchema(ISchema schema, IServiceContext context) {
Map<String, Object> ret = new LinkedHashMap<>();
if (schema == null) {
return ret;
}

if (schema.isObjSchema()) {
toObjectSchema(ret, schema, context);
} else if (schema.isListSchema()) {
ret.put("type", "array");
addArraySpecificProps(ret, schema);
ret.put("items", toJsonSchema(schema.getItemSchema(), context));
} else if (schema.isUnionSchema()) {
List<ISchema> schemas = schema.getOneOf();
if (schemas != null) {
List<Map<String, Object>> list = new ArrayList<>(schemas.size());
for (ISchema subSchema : schemas) {
list.add(toJsonSchema(subSchema, context));
}
ret.put("anyOf", schemas);
}
} else {
toSimpleSchema(ret, schema, context);
}
return ret;
}

void addArraySpecificProps(Map<String, Object> ret, ISchema schema) {
if (schema.getMinItems() != null)
ret.put("minItems", schema.getMinItems());
if (schema.getMaxItems() != null) {
ret.put("maxItems", schema.getMaxItems());
}
}

void addObjectSpecificProps(Map<String, Object> ret, IObjSchema schema) {
if (schema.getMinProperties() != null) {
ret.put("minProperties", schema.getMinProperties());
}
if (schema.getMaxProperties() != null) {
ret.put("maxProperties", schema.getMaxProperties());
}
}

void toObjectSchema(Map<String, Object> ret, IObjSchema schema, IServiceContext context) {
ret.put("type", "object");
addObjectSpecificProps(ret, schema);

List<String> required = new ArrayList<>();
List<? extends IObjPropMeta> props = schema.getProps();
Map<String, Object> propSchemas = new LinkedHashMap<>();
if (props != null) {
props.forEach(prop -> {
if (prop.isMandatory())
required.add(prop.getName());

propSchemas.put(prop.getName(), toJsonSchema(prop.getSchema(), context));
});
}
ret.put("properties", propSchemas);
if (!required.isEmpty())
ret.put("required", required);
}

void toSimpleSchema(Map<String, Object> ret, ISchema schema, IServiceContext context) {
if (schema == null)
return;

StdDataType dataType = schema.getStdDataType();
if (dataType == null)
dataType = StdDataType.STRING;

if (dataType == StdDataType.MAP) {
toMapSchema(ret);
} else {
String jsonType = dataType.getJsonType();
ret.put("type", jsonType);
if (schema.getMax() != null) {
ret.put("maximum", schema.getMax());
}
if (schema.getMin() != null) {
ret.put("minimum", schema.getMin());
}

if (schema.getMinLength() != null)
ret.put("minLength", schema.getMinLength());
if (schema.getMaxLength() != null)
ret.put("maxLength", schema.getMaxLength());
if (schema.getPattern() != null)
ret.put("pattern", schema.getPattern());

String format = getFormat(schema);
if (format != null)
ret.put("format", format);

String dict = schema.getDict();
if (dict != null) {
String locale = ContextProvider.currentLocale();
DictBean dictBean = DictProvider.instance().getDict(locale, dict, context.getCache(), context);
if (dictBean != null) {
ret.put("enum", dictBean.getValues());
}
}
}
}

protected String getFormat(ISchema schema) {
StdDataType dataType = schema.getStdDataType();
if (dataType == StdDataType.DATETIME)
return "date-time";
if (dataType == StdDataType.TIME)
return "time";
if (dataType == StdDataType.DATE)
return "date";

if (dataType == StdDataType.DURATION)
return "duration";

String domain = schema.getStdDomain();
if (domain == null)
return null;
switch (domain) {
case "email":
return "email";
case "url":
return "url";
case "ipv4":
return "ipv4";
case "ipv6":
return "ipv6";
}
return null;
}

void toMapSchema(Map<String, Object> ret) {
ret.put("type", "object");
ret.put("additionalProperties", true);
Map<String, Object> pattern = new HashMap<>();
pattern.put(".*", new HashMap<>());
ret.put("patternProperties", pattern);
}
}

0 comments on commit 3104b89

Please sign in to comment.