S8XMLFileParser.java 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package com.ssssssss.utils;
  2. import com.ssssssss.enums.SqlMode;
  3. import com.ssssssss.scripts.ForeachSqlNode;
  4. import com.ssssssss.scripts.IfSqlNode;
  5. import com.ssssssss.scripts.SqlNode;
  6. import com.ssssssss.scripts.TextSqlNode;
  7. import com.ssssssss.session.SqlStatement;
  8. import com.ssssssss.session.ValidateStatement;
  9. import com.ssssssss.session.XMLStatement;
  10. import org.apache.commons.lang3.StringUtils;
  11. import org.apache.commons.lang3.math.NumberUtils;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import org.w3c.dom.Document;
  15. import org.w3c.dom.Node;
  16. import org.w3c.dom.NodeList;
  17. import org.xml.sax.SAXException;
  18. import javax.xml.parsers.DocumentBuilderFactory;
  19. import javax.xml.parsers.ParserConfigurationException;
  20. import javax.xml.xpath.XPathConstants;
  21. import java.io.File;
  22. import java.io.IOException;
  23. import java.util.ArrayList;
  24. import java.util.Arrays;
  25. import java.util.List;
  26. import java.util.Map;
  27. /**
  28. * xml文件解析
  29. */
  30. public class S8XMLFileParser {
  31. private static Logger logger = LoggerFactory.getLogger(S8XMLFileParser.class);
  32. private static final List<String> TAG_NAMES = Arrays.asList("select-list", "select-one", "insert", "update", "delete");
  33. /**
  34. * 解析xml文件
  35. */
  36. static XMLStatement parse(File file) {
  37. XMLStatement statement = null;
  38. try {
  39. Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
  40. // 解析根节点
  41. statement = parseRoot(document);
  42. // 解析验证节点
  43. parseValidateStatement(document.getElementsByTagName("validate"), statement);
  44. // 解析select/insert/update/delete节点
  45. for (String tagName : TAG_NAMES) {
  46. statement.addSqlStatement(parseSqlStatement(statement, tagName, document));
  47. }
  48. } catch (SAXException | IOException | ParserConfigurationException e) {
  49. logger.error("解析S8XML文件出错", e);
  50. }
  51. return statement;
  52. }
  53. /**
  54. * 解析Validate节点
  55. */
  56. private static void parseValidateStatement(NodeList nodeList, XMLStatement xmlStatement) {
  57. for (int i = 0, len = nodeList.getLength(); i < len; i++) {
  58. Node node = nodeList.item(i);
  59. String id = DomUtils.getNodeAttributeValue(node, "id");
  60. Assert.isNotBlank(id, "validate节点必须要有id属性");
  61. String code = DomUtils.getNodeAttributeValue(node, "code");
  62. String message = DomUtils.getNodeAttributeValue(node, "message");
  63. message = StringUtils.isBlank(message) ? "参数校验失败" : message;
  64. xmlStatement.addValidateStatement(new ValidateStatement(id, NumberUtils.toInt(code, 0), message, (NodeList) DomUtils.evaluate("param", node, XPathConstants.NODESET)));
  65. }
  66. }
  67. /**
  68. * 解析根节点
  69. */
  70. private static XMLStatement parseRoot(Document document) {
  71. XMLStatement statement = new XMLStatement();
  72. //解析请求路径
  73. statement.setRequestMapping(document.getDocumentElement().getAttribute("request-mapping"));
  74. return statement;
  75. }
  76. /**
  77. * 解析节点
  78. */
  79. private static List<SqlStatement> parseSqlStatement(XMLStatement xmlStatement, String tagName, Document document) {
  80. List<SqlStatement> sqlStatements = new ArrayList<>();
  81. NodeList nodeList = document.getElementsByTagName(tagName);
  82. for (int i = 0, len = nodeList.getLength(); i < len; i++) {
  83. Node item = nodeList.item(i);
  84. SqlStatement sqlStatement = new SqlStatement();
  85. sqlStatement.setXmlStatement(xmlStatement);
  86. String validate = DomUtils.getNodeAttributeValue(item, "validate");
  87. if (StringUtils.isNotBlank(validate)) {
  88. // 支持多个验证
  89. for (String validateId : validate.split(",")) {
  90. Assert.isTrue(xmlStatement.containsValidateStatement(validateId), String.format("找不到验证节点[%s]", validateId));
  91. sqlStatement.addValidate(validateId);
  92. }
  93. }
  94. // 设置SqlMode
  95. sqlStatement.setSqlMode(SqlMode.valueOf(item.getNodeName().toUpperCase().replace("-", "_")));
  96. String requestMapping = DomUtils.getNodeAttributeValue(item, "request-mapping");
  97. Assert.isNotBlank(requestMapping, "请求方法不能为空!");
  98. // 设置请求路径
  99. sqlStatement.setRequestMapping(StringUtils.defaultString(xmlStatement.getRequestMapping()) + requestMapping);
  100. // 设置请求方法
  101. sqlStatement.setRequestMethod(DomUtils.getNodeAttributeValue(item, "request-method"));
  102. String returnType = DomUtils.getNodeAttributeValue(item, "return-type");
  103. if ("int".equalsIgnoreCase(returnType)) {
  104. sqlStatement.setReturnType(Integer.class);
  105. } else if ("double".equalsIgnoreCase(returnType)) {
  106. sqlStatement.setReturnType(Double.class);
  107. } else if ("long".equalsIgnoreCase(returnType)) {
  108. sqlStatement.setReturnType(Long.class);
  109. } else if ("string".equalsIgnoreCase(returnType)) {
  110. sqlStatement.setReturnType(String.class);
  111. } else if ("boolean".equalsIgnoreCase(returnType)) {
  112. sqlStatement.setReturnType(Boolean.class);
  113. } else {
  114. sqlStatement.setReturnType(Map.class);
  115. }
  116. if (SqlMode.SELECT_LIST == sqlStatement.getSqlMode()) {
  117. //设置是否是分页
  118. sqlStatement.setPagination("true".equalsIgnoreCase(DomUtils.getNodeAttributeValue(item, "page")));
  119. }
  120. SqlNode root = new TextSqlNode("");
  121. // 解析sql语句
  122. parseNodeList(root, document, item.getChildNodes());
  123. sqlStatement.setSqlNode(root);
  124. sqlStatements.add(sqlStatement);
  125. }
  126. return sqlStatements;
  127. }
  128. /**
  129. * 递归解析子节点
  130. */
  131. private static void parseNodeList(SqlNode sqlNode, Document document, NodeList nodeList) {
  132. for (int i = 0, len = nodeList.getLength(); i < len; i++) {
  133. Node node = nodeList.item(i);
  134. if (node.getNodeType() == Node.TEXT_NODE) {
  135. sqlNode.addChildNode(new TextSqlNode(node.getNodeValue().trim()));
  136. } else if (node.getNodeType() != Node.COMMENT_NODE) {
  137. String nodeName = node.getNodeName();
  138. SqlNode childNode;
  139. if ("foreach".equals(nodeName)) {
  140. childNode = parseForeachSqlNode(node);
  141. } else if ("if".equals(nodeName)) {
  142. childNode = parseIfSqlNode(node);
  143. } else if ("include".equalsIgnoreCase(nodeName)) {
  144. String refId = DomUtils.getNodeAttributeValue(node, "refid");
  145. Assert.isNotBlank(refId, "refid 不能为空!");
  146. Node refSqlNode = (Node) DomUtils.evaluate(String.format("//sql[@id=\"%s\"]", refId), document, XPathConstants.NODE);
  147. Assert.isNotNull(refSqlNode, "找不到sql[" + refId + "]");
  148. childNode = new TextSqlNode(refSqlNode.getTextContent().trim());
  149. } else {
  150. logger.error("不支持的标签:[{}]", nodeName);
  151. return;
  152. }
  153. sqlNode.addChildNode(childNode);
  154. if (node.hasChildNodes()) {
  155. parseNodeList(childNode, document, node.getChildNodes());
  156. }
  157. }
  158. }
  159. }
  160. /**
  161. * 解析foreach节点
  162. */
  163. private static ForeachSqlNode parseForeachSqlNode(Node node) {
  164. ForeachSqlNode foreachSqlNode = new ForeachSqlNode();
  165. foreachSqlNode.setCollection(DomUtils.getNodeAttributeValue(node, "collection"));
  166. foreachSqlNode.setSeparator(DomUtils.getNodeAttributeValue(node, "separator"));
  167. foreachSqlNode.setClose(DomUtils.getNodeAttributeValue(node, "close"));
  168. foreachSqlNode.setOpen(DomUtils.getNodeAttributeValue(node, "open"));
  169. foreachSqlNode.setItem(DomUtils.getNodeAttributeValue(node, "item"));
  170. return foreachSqlNode;
  171. }
  172. /**
  173. * 解析if节点
  174. */
  175. private static IfSqlNode parseIfSqlNode(Node node) {
  176. return new IfSqlNode(DomUtils.getNodeAttributeValue(node, "test"));
  177. }
  178. }