|
@@ -6,8 +6,10 @@ import com.ssssssss.scripts.IfSqlNode;
|
|
|
import com.ssssssss.scripts.SqlNode;
|
|
|
import com.ssssssss.scripts.TextSqlNode;
|
|
|
import com.ssssssss.session.SqlStatement;
|
|
|
+import com.ssssssss.session.ValidateStatement;
|
|
|
import com.ssssssss.session.XMLStatement;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.apache.commons.lang3.math.NumberUtils;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.w3c.dom.Document;
|
|
@@ -17,11 +19,13 @@ import org.xml.sax.SAXException;
|
|
|
|
|
|
import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
|
+import javax.xml.xpath.XPathConstants;
|
|
|
import java.io.File;
|
|
|
import java.io.IOException;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
|
|
|
|
|
|
* xml文件解析
|
|
@@ -30,20 +34,22 @@ public class S8XMLFileParser {
|
|
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(S8XMLFileParser.class);
|
|
|
|
|
|
- private static final List<String> TAG_NAMES = Arrays.asList("select", "insert", "update", "delete");
|
|
|
+ private static final List<String> TAG_NAMES = Arrays.asList("select-list", "select-one", "insert", "update", "delete");
|
|
|
|
|
|
|
|
|
* 解析xml文件
|
|
|
*/
|
|
|
- public static XMLStatement parse(File file) {
|
|
|
+ static XMLStatement parse(File file) {
|
|
|
XMLStatement statement = null;
|
|
|
try {
|
|
|
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
|
|
|
-
|
|
|
+
|
|
|
statement = parseRoot(document);
|
|
|
+
|
|
|
+ parseValidateStatement(document.getElementsByTagName("validate"), statement);
|
|
|
|
|
|
for (String tagName : TAG_NAMES) {
|
|
|
- statement.addSqlStatement(parseSqlStatement(statement, document.getElementsByTagName(tagName)));
|
|
|
+ statement.addSqlStatement(parseSqlStatement(statement, tagName, document));
|
|
|
}
|
|
|
} catch (SAXException | IOException | ParserConfigurationException e) {
|
|
|
logger.error("解析S8XML文件出错", e);
|
|
@@ -51,6 +57,21 @@ public class S8XMLFileParser {
|
|
|
return statement;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ * 解析Validate节点
|
|
|
+ */
|
|
|
+ private static void parseValidateStatement(NodeList nodeList, XMLStatement xmlStatement) {
|
|
|
+ for (int i = 0, len = nodeList.getLength(); i < len; i++) {
|
|
|
+ Node node = nodeList.item(i);
|
|
|
+ String id = DomUtils.getNodeAttributeValue(node, "id");
|
|
|
+ Assert.isNotBlank(id, "validate节点必须要有id属性");
|
|
|
+ String code = DomUtils.getNodeAttributeValue(node, "code");
|
|
|
+ String message = DomUtils.getNodeAttributeValue(node, "message");
|
|
|
+ message = StringUtils.isBlank(message) ? "参数校验失败" : message;
|
|
|
+ xmlStatement.addValidateStatement(new ValidateStatement(id, NumberUtils.toInt(code, 0), message, (NodeList) DomUtils.evaluate("param", node, XPathConstants.NODESET)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
* 解析根节点
|
|
|
*/
|
|
@@ -64,40 +85,51 @@ public class S8XMLFileParser {
|
|
|
|
|
|
* 解析节点
|
|
|
*/
|
|
|
- private static List<SqlStatement> parseSqlStatement(XMLStatement xmlStatement, NodeList nodeList) {
|
|
|
+ private static List<SqlStatement> parseSqlStatement(XMLStatement xmlStatement, String tagName, Document document) {
|
|
|
List<SqlStatement> sqlStatements = new ArrayList<>();
|
|
|
+ NodeList nodeList = document.getElementsByTagName(tagName);
|
|
|
for (int i = 0, len = nodeList.getLength(); i < len; i++) {
|
|
|
Node item = nodeList.item(i);
|
|
|
SqlStatement sqlStatement = new SqlStatement();
|
|
|
sqlStatement.setXmlStatement(xmlStatement);
|
|
|
- String requestMapping = getNodeAttributeValue(item, "request-mapping");
|
|
|
- Assert.isNotBlank(requestMapping,"请求方法不能为空!");
|
|
|
+ String validate = DomUtils.getNodeAttributeValue(item, "validate");
|
|
|
+ if (StringUtils.isNotBlank(validate)) {
|
|
|
+
|
|
|
+ for (String validateId : validate.split(",")) {
|
|
|
+ Assert.isTrue(xmlStatement.containsValidateStatement(validateId), String.format("找不到验证节点[%s]", validateId));
|
|
|
+ sqlStatement.addValidate(validateId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ sqlStatement.setSqlMode(SqlMode.valueOf(item.getNodeName().toUpperCase().replace("-", "_")));
|
|
|
+
|
|
|
+ String requestMapping = DomUtils.getNodeAttributeValue(item, "request-mapping");
|
|
|
+ Assert.isNotBlank(requestMapping, "请求方法不能为空!");
|
|
|
|
|
|
sqlStatement.setRequestMapping(StringUtils.defaultString(xmlStatement.getRequestMapping()) + requestMapping);
|
|
|
|
|
|
- sqlStatement.setRequestMethod(getNodeAttributeValue(item, "request-method"));
|
|
|
- String returnType = getNodeAttributeValue(item, "return-type");
|
|
|
- if("int".equalsIgnoreCase(returnType)){
|
|
|
+ sqlStatement.setRequestMethod(DomUtils.getNodeAttributeValue(item, "request-method"));
|
|
|
+ String returnType = DomUtils.getNodeAttributeValue(item, "return-type");
|
|
|
+ if ("int".equalsIgnoreCase(returnType)) {
|
|
|
sqlStatement.setReturnType(Integer.class);
|
|
|
- sqlStatement.setSqlMode(SqlMode.SELECT_NUMBER);
|
|
|
- }else if("double".equalsIgnoreCase(returnType)){
|
|
|
- sqlStatement.setSqlMode(SqlMode.SELECT_NUMBER);
|
|
|
+ } else if ("double".equalsIgnoreCase(returnType)) {
|
|
|
sqlStatement.setReturnType(Double.class);
|
|
|
- }else if("long".equalsIgnoreCase(returnType)){
|
|
|
- sqlStatement.setSqlMode(SqlMode.SELECT_NUMBER);
|
|
|
+ } else if ("long".equalsIgnoreCase(returnType)) {
|
|
|
sqlStatement.setReturnType(Long.class);
|
|
|
- }else if("string".equalsIgnoreCase(returnType)){
|
|
|
+ } else if ("string".equalsIgnoreCase(returnType)) {
|
|
|
sqlStatement.setReturnType(String.class);
|
|
|
- }else if("map".equalsIgnoreCase(returnType)){
|
|
|
- sqlStatement.setSqlMode(SqlMode.SELECT_ONE);
|
|
|
- }else{
|
|
|
- sqlStatement.setSqlMode(SqlMode.SELECT_LIST);
|
|
|
+ } else if ("boolean".equalsIgnoreCase(returnType)) {
|
|
|
+ sqlStatement.setReturnType(Boolean.class);
|
|
|
+ } else {
|
|
|
+ sqlStatement.setReturnType(Map.class);
|
|
|
+ }
|
|
|
+ if (SqlMode.SELECT_LIST == sqlStatement.getSqlMode()) {
|
|
|
|
|
|
- sqlStatement.setPagination("true".equalsIgnoreCase(getNodeAttributeValue(item,"page")));
|
|
|
+ sqlStatement.setPagination("true".equalsIgnoreCase(DomUtils.getNodeAttributeValue(item, "page")));
|
|
|
}
|
|
|
SqlNode root = new TextSqlNode("");
|
|
|
|
|
|
- parseNodeList(root, item.getChildNodes());
|
|
|
+ parseNodeList(root, document, item.getChildNodes());
|
|
|
sqlStatement.setSqlNode(root);
|
|
|
sqlStatements.add(sqlStatement);
|
|
|
}
|
|
@@ -107,52 +139,46 @@ public class S8XMLFileParser {
|
|
|
|
|
|
* 递归解析子节点
|
|
|
*/
|
|
|
- private static void parseNodeList(SqlNode sqlNode, NodeList nodeList) {
|
|
|
+ private static void parseNodeList(SqlNode sqlNode, Document document, NodeList nodeList) {
|
|
|
for (int i = 0, len = nodeList.getLength(); i < len; i++) {
|
|
|
Node node = nodeList.item(i);
|
|
|
if (node.getNodeType() == Node.TEXT_NODE) {
|
|
|
sqlNode.addChildNode(new TextSqlNode(node.getNodeValue().trim()));
|
|
|
- } else if(node.getNodeType() != Node.COMMENT_NODE){
|
|
|
+ } else if (node.getNodeType() != Node.COMMENT_NODE) {
|
|
|
String nodeName = node.getNodeName();
|
|
|
- SqlNode childNode = null;
|
|
|
+ SqlNode childNode;
|
|
|
if ("foreach".equals(nodeName)) {
|
|
|
childNode = parseForeachSqlNode(node);
|
|
|
} else if ("if".equals(nodeName)) {
|
|
|
childNode = parseIfSqlNode(node);
|
|
|
+ } else if ("include".equalsIgnoreCase(nodeName)) {
|
|
|
+ String refId = DomUtils.getNodeAttributeValue(node, "refid");
|
|
|
+ Assert.isNotBlank(refId, "refid 不能为空!");
|
|
|
+ Node refSqlNode = (Node) DomUtils.evaluate(String.format("//sql[@id=\"%s\"]", refId), document, XPathConstants.NODE);
|
|
|
+ Assert.isNotNull(refSqlNode, "找不到sql[" + refId + "]");
|
|
|
+ childNode = new TextSqlNode(refSqlNode.getTextContent().trim());
|
|
|
} else {
|
|
|
logger.error("不支持的标签:[{}]", nodeName);
|
|
|
return;
|
|
|
}
|
|
|
sqlNode.addChildNode(childNode);
|
|
|
if (node.hasChildNodes()) {
|
|
|
- parseNodeList(childNode, node.getChildNodes());
|
|
|
+ parseNodeList(childNode, document, node.getChildNodes());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- * 获取节点属性
|
|
|
- *
|
|
|
- * @param node 节点
|
|
|
- * @param attributeKey 属性名
|
|
|
- * @return 节点属性值,未设置时返回null
|
|
|
- */
|
|
|
- private static String getNodeAttributeValue(Node node, String attributeKey) {
|
|
|
- Node item = node.getAttributes().getNamedItem(attributeKey);
|
|
|
- return item != null ? item.getNodeValue() : null;
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
* 解析foreach节点
|
|
|
*/
|
|
|
private static ForeachSqlNode parseForeachSqlNode(Node node) {
|
|
|
ForeachSqlNode foreachSqlNode = new ForeachSqlNode();
|
|
|
- foreachSqlNode.setCollection(getNodeAttributeValue(node, "collection"));
|
|
|
- foreachSqlNode.setSeparator(getNodeAttributeValue(node, "separator"));
|
|
|
- foreachSqlNode.setClose(getNodeAttributeValue(node, "close"));
|
|
|
- foreachSqlNode.setOpen(getNodeAttributeValue(node, "open"));
|
|
|
- foreachSqlNode.setItem(getNodeAttributeValue(node, "item"));
|
|
|
+ foreachSqlNode.setCollection(DomUtils.getNodeAttributeValue(node, "collection"));
|
|
|
+ foreachSqlNode.setSeparator(DomUtils.getNodeAttributeValue(node, "separator"));
|
|
|
+ foreachSqlNode.setClose(DomUtils.getNodeAttributeValue(node, "close"));
|
|
|
+ foreachSqlNode.setOpen(DomUtils.getNodeAttributeValue(node, "open"));
|
|
|
+ foreachSqlNode.setItem(DomUtils.getNodeAttributeValue(node, "item"));
|
|
|
return foreachSqlNode;
|
|
|
}
|
|
|
|
|
@@ -160,6 +186,6 @@ public class S8XMLFileParser {
|
|
|
* 解析if节点
|
|
|
*/
|
|
|
private static IfSqlNode parseIfSqlNode(Node node) {
|
|
|
- return new IfSqlNode(getNodeAttributeValue(node, "test"));
|
|
|
+ return new IfSqlNode(DomUtils.getNodeAttributeValue(node, "test"));
|
|
|
}
|
|
|
}
|