All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xson.common.validate.util.XMLRuleBuilder Maven / Gradle / Ivy

Go to download

xco-validate based XCO, using xml language to describe data validation framework.

The newest version!
package org.xson.common.validate.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xson.common.validate.Checker;
import org.xson.common.validate.Container;
import org.xson.common.validate.Rule;
import org.xson.common.validate.RuleDef;
import org.xson.common.validate.RuleEnum;
import org.xson.common.validate.RuleGroup;
import org.xson.common.validate.RuleGroupItem;
import org.xson.common.validate.TypeEnum;

public class XMLRuleBuilder {

	private Logger					logger				= Logger.getLogger(XMLRuleBuilder.class);
	private XPathParser				parser				= null;
	private String					ns					= "";
	private XmlNodeWrapper			root				= null;
	private Map	localDefMap			= new HashMap();
	private Map	globleDefMap		= null;
	private Map	ruleGroupMap		= null;
	private Map	customCheckerMap	= null;

	public XMLRuleBuilder(InputStream inputStream, Map globleDefMap, Map ruleGroupMap,
			Map customCheckerMap) {
		this.globleDefMap = globleDefMap;
		this.ruleGroupMap = ruleGroupMap;
		this.customCheckerMap = customCheckerMap;
		this.parser = new XPathParser(inputStream);
		this.root = this.parser.evalNode("/validate");
		this.ns = this.root.getStringAttribute("ns", "");
	}

	public void parseDefNode() {
		try {
			buildDefNodes(this.root.evalNodes("def"));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private void addDefNode(RuleDef ruleDef) {
		localDefMap.put(ruleDef.getId(), ruleDef);
		globleDefMap.put(getFullId(ruleDef.getId()), ruleDef);
		logger.info("Add  :" + ruleDef.getId());
	}

	public void parseRuleGroupNode() {
		try {
			buildRuleGroupNodes(this.root.evalNodes("ruleGroup"));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private void addRuleGroup(RuleGroup ruleGroup) {
		ruleGroupMap.put(getFullId(ruleGroup.getId()), ruleGroup);
		logger.info("Add  :" + ruleGroup.getId());
	}

	private void buildDefNodes(List contexts) {
		// List list = new ArrayList();
		for (XmlNodeWrapper context : contexts) {
			String id = StringUtils.trim(context.getStringAttribute("id")); // xml validation
			checkDefId(id);
			List ruleNodes = context.evalNodes("rule");
			if (ruleNodes.size() < 1) {
				throw new RuntimeException(" node is empty: " + id);
			}
			List ruleList = new ArrayList<>();
			for (XmlNodeWrapper ruleNode : ruleNodes) {
				Rule rule = null;
				String checkerId = StringUtils.trim(ruleNode.getStringAttribute("checker"));
				if (null == checkerId) {
					String name = StringUtils.trim(ruleNode.getStringAttribute("name"));
					RuleEnum ruleEnum = RuleEnum.getEnum(name);
					if (null == ruleEnum) {
						throw new RuntimeException("Invalid rule: " + name);
					}
					String value = StringUtils.trim(ruleNode.getStringAttribute("value"));
					if (null == value) {
						value = getNodeBody(ruleNode);
					}
					if (null == value) {
						throw new RuntimeException("Invalid rule value.");
					}
					rule = new Rule(name, value);
				} else {
					// checkerId
					Checker checker = this.customCheckerMap.get(checkerId);
					if (null == checker) {
						throw new RuntimeException("Reference checker does not exist: " + checkerId);
					}
					rule = new Rule(checker);
				}
				ruleList.add(rule);
			}
			RuleDef ruleDef = new RuleDef(id, ruleList);
			addDefNode(ruleDef);
		}
	}

	private String getNodeBody(XmlNodeWrapper ruleNode) {
		NodeList children = ruleNode.getNode().getChildNodes();
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < children.getLength(); i++) {
			XmlNodeWrapper child = ruleNode.newXMlNode(children.item(i));
			if (child.getNode().getNodeType() == Node.CDATA_SECTION_NODE || child.getNode().getNodeType() == Node.TEXT_NODE) {
				String data = child.getStringBody("").trim();
				if (data.length() > 0) {
					builder.append(data);
				}
			}
		}
		String value = builder.toString();
		if (value.length() > 0) {
			return value;
		}
		return null;
	}

	private void buildRuleGroupNodes(List contexts) {
		for (XmlNodeWrapper context : contexts) {
			String id = StringUtils.trim(context.getStringAttribute("id")); // xml validation
			checkRuleGroupId(id);

			String desc = StringUtils.trim(context.getStringAttribute("desc"));

			List itemNodes = context.evalNodes("item");
			if (itemNodes.size() < 1) {
				throw new RuntimeException(" node is empty: " + id);
			}

			String groupMessage = StringUtils.trim(context.getStringAttribute("message"));

			List ruleGroupItemList = new ArrayList();

			for (XmlNodeWrapper itemNode : itemNodes) {
				String fieldName = StringUtils.trim(itemNode.getStringAttribute("name"));// xml validation
				String _type = StringUtils.trim(itemNode.getStringAttribute("type"));// xml validation
				TypeEnum fieldType = TypeEnum.getEnum(_type);// xml validation
				if (null == fieldType) {
					throw new RuntimeException("Invalid fieldType: " + _type);
				}
				String _require = StringUtils.trim(itemNode.getStringAttribute("require"));
				boolean require = true;
				if (null != _require) {
					require = Boolean.parseBoolean(_require);
				}

				List ruleList = new ArrayList();

				List ruleNodes = itemNode.evalNodes("rule");
				if (ruleNodes.size() > 0) {
					for (XmlNodeWrapper ruleNode : ruleNodes) {
						Rule rule = null;
						String checkerId = StringUtils.trim(ruleNode.getStringAttribute("checker"));
						if (null == checkerId) {
							String name = StringUtils.trim(ruleNode.getStringAttribute("name"));
							RuleEnum ruleEnum = RuleEnum.getEnum(name);
							if (null == ruleEnum) {
								throw new RuntimeException("Invalid rule: " + name);
							}
							String value = StringUtils.trim(ruleNode.getStringAttribute("value"));
							if (null == value) {
								value = getNodeBody(ruleNode);
							}
							if (null == value) {
								throw new RuntimeException("Invalid rule value.");
							}
							rule = new Rule(name, value);
							rule.parseValue(fieldType, ruleEnum, id + ":" + name);
						} else {
							// checkerId
							Checker checker = this.customCheckerMap.get(checkerId);
							if (null == checker) {
								throw new RuntimeException("Reference checker does not exist: " + checkerId);
							}
							rule = new Rule(checker);
						}
						ruleList.add(rule);
					}
				}

				String ref = StringUtils.trim(itemNode.getStringAttribute("ref"));
				if (null != ref) {
					List ruleDefList = getRuleDefs(ref, id);
					copyRule(ruleList, ruleDefList, fieldType);// 复制RULE
				}

				// 允许没有规则的验证
				// if (require && 0 == ruleList.size()) {
				// throw new RuntimeException("The group does not exist to verify items: " + id);
				// }

				String itemMessage = StringUtils.trim(itemNode.getStringAttribute("message"));
				// if (null == itemMessage) {
				// itemMessage = groupMessage;
				// }

				String defaultValue = StringUtils.trim(itemNode.getStringAttribute("defaultValue"));
				String itemDesc = StringUtils.trim(itemNode.getStringAttribute("desc"));
				RuleGroupItem ruleGroupItem = new RuleGroupItem(fieldName, fieldType, ruleList, require, itemMessage, defaultValue, itemDesc);
				ruleGroupItemList.add(ruleGroupItem);
			}
			RuleGroup ruleGroup = new RuleGroup(id, ruleGroupItemList, desc, groupMessage);
			addRuleGroup(ruleGroup);
		}
	}

	private List getRuleDefs(String ref, String id) {
		List list = new ArrayList();
		String[] array = ref.split(",");
		for (String temp : array) {
			String refId = temp.trim();
			RuleDef ruleDef = null;
			if (temp.indexOf(Container.nsSeparator) == -1) {
				ruleDef = this.localDefMap.get(refId);
			} else {
				ruleDef = this.globleDefMap.get(refId);
			}
			if (null == ruleDef) {
				throw new RuntimeException("Ref does not exist: " + refId + ", in ruleGroup: " + id);
			}
			list.add(ruleDef);
		}
		if (list.size() == 0) {
			throw new RuntimeException("Ref does not exist: " + ref + ", in ruleGroup: " + id);
		}
		return list;
	}

	private String getFullId(String id) {
		if (null == ns || "".equals(ns)) {
			return id;
		}
		return ns + Container.nsSeparator + id;
	}

	private void checkDefId(String id) {
		if (null != this.localDefMap.get(id)) {
			throw new RuntimeException("Duplicate : " + id);
		}
		if (null != this.globleDefMap.get(getFullId(id))) {
			throw new RuntimeException("Duplicate : " + id);
		}
	}

	private void checkRuleGroupId(String id) {
		if (null != this.ruleGroupMap.get(getFullId(id))) {
			throw new RuntimeException("Duplicate : " + id);
		}
	}

	private void copyRule(List ruleList, List ruleDefList, TypeEnum fieldType) {
		for (RuleDef ruleDef : ruleDefList) {
			List srcRuleList = ruleDef.getRule();
			for (Rule rule : srcRuleList) {
				Rule newRule = rule.copy();
				if (null == newRule.getChecker()) {
					newRule.parseValue(fieldType, RuleEnum.getEnum(newRule.getName()), ruleDef.getId());
				}
				ruleList.add(newRule);
			}
		}
	}

	public void clear() {
		this.localDefMap = null;
		this.globleDefMap = null;
		this.ruleGroupMap = null;
		this.customCheckerMap = null;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy