package com.smtaiserver.smtaiserver.gismap; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.tree.DefaultText; import com.smtservlet.util.SMTStatic; public class SMTMapLayerSqlXml { /////////////////////////////////////////////////////////////////////////////////////// private static class SQLXMLExecArg { public List _sqlParams; public StringBuilder _sbSQLText = new StringBuilder(); public Map _mapArgs; public SQLXMLExecArg(Map mapArgs, List sqlParams) { _mapArgs = mapArgs; _sqlParams = sqlParams; } public Object getArgValue(String key) throws Exception { if(_mapArgs == null) throw new Exception("can't find key : " + key); Object value = _mapArgs.get(key); if(value == null) throw new Exception("can't find key : " + key); return value; } } /////////////////////////////////////////////////////////////////////////////////////// private static abstract class SQLXMLNode { public abstract void execute(SQLXMLExecArg execArg) throws Exception; } /////////////////////////////////////////////////////////////////////////////////////// private static class SQLXMLNodePARAM extends SQLXMLNode { private String _key; public SQLXMLNodePARAM(Element xmlRoot) throws Exception { _key = SMTStatic.getXmlAttr(xmlRoot, "key"); } @Override public void execute(SQLXMLExecArg execArg) throws Exception { execArg._sbSQLText.append("?"); execArg._sqlParams.add(execArg.getArgValue(_key)); } } /////////////////////////////////////////////////////////////////////////////////////// private static class SQLXMLNodeLIKE_PARAM extends SQLXMLNode { private String _key; public SQLXMLNodeLIKE_PARAM(Element xmlRoot) throws Exception { _key = SMTStatic.getXmlAttr(xmlRoot, "key"); } @Override public void execute(SQLXMLExecArg execArg) throws Exception { execArg._sbSQLText.append("?"); execArg._sqlParams.add("%" + execArg.getArgValue(_key) + "%"); } } /////////////////////////////////////////////////////////////////////////////////////// private static class SQLXMLNodeSQL extends SQLXMLNode { private List _listChildren = new ArrayList<>(); public SQLXMLNodeSQL(Element xmlRoot) throws Exception { for (Iterator iterInner = xmlRoot.nodeIterator(); iterInner.hasNext();) { Node nodeInner = iterInner.next(); if(nodeInner.getNodeType() == Node.TEXT_NODE) { String text = ((DefaultText)nodeInner).getText(); int lastPos = _listChildren.size() - 1; if(lastPos >= 0 && _listChildren.get(lastPos) instanceof String) { _listChildren.set(lastPos, (String)_listChildren.get(lastPos) + text); } else { _listChildren.add(text); } } else { _listChildren.add(createSQLXMLNode((Element)nodeInner)); } } } @Override public void execute(SQLXMLExecArg execArg) throws Exception { for(Object oxmlNode : _listChildren) { if(oxmlNode instanceof String) { execArg._sbSQLText.append(oxmlNode); } else if(oxmlNode instanceof SQLXMLNode) { ((SQLXMLNode)oxmlNode).execute(execArg); } } } } /////////////////////////////////////////////////////////////////////////////////////// private SQLXMLNode _SQLXMLNode; private static SQLXMLNode createSQLXMLNode(Element xmlRoot) throws Exception { String name = xmlRoot.getName().toUpperCase(); if("DRAW_SQL".equals(name)) return new SQLXMLNodeSQL(xmlRoot); if("SEARCH_SQL".equals(name)) return new SQLXMLNodeSQL(xmlRoot); if("PARAM".equals(name)) return new SQLXMLNodePARAM(xmlRoot); if("LIKE_PARAM".equals(name)) return new SQLXMLNodeLIKE_PARAM(xmlRoot); else throw new Exception("unknow sqlxml type : " + name); } public SMTMapLayerSqlXml(Element rootElement) throws Exception { _SQLXMLNode = createSQLXMLNode(rootElement); } public void createSQL(Map mapArgs, StringBuilder sbSQL, List sqlParams) throws Exception { SQLXMLExecArg execArg = new SQLXMLExecArg(mapArgs, sqlParams); _SQLXMLNode.execute(execArg); sbSQL.append(execArg._sbSQLText.toString()); } }