This commit is contained in:
2020-06-19 11:56:29 +06:00
5 changed files with 2767 additions and 23 deletions

File diff suppressed because it is too large Load Diff

457
metadata/dbms/DBMSTree.java Normal file
View File

@ -0,0 +1,457 @@
package kz.goodssales.GoodsSales.dbms;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.ServletContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.context.ServletContextAware;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import tctable.Tools;
import tools.User;
import tools.XMLTools;
@Controller
@SessionAttributes( { "user" }) //Сесионный объект
public class DBMSTree implements ServletContextAware {
private static final Logger logger = LoggerFactory.getLogger(kz.goodssales.GoodsSales.dbms.DBMSTree.class);
private ServletContext context;
//If not created object "user", create him.
@ModelAttribute("user")
public User populatePerson() {
return new User("none");
}
@RequestMapping(value = "/tree",method = RequestMethod.POST,produces = "application/xml; charset=utf-8")
@ResponseBody
public Object ajaxTamer(@ModelAttribute User user,@RequestBody byte[] reqData,@RequestParam(required=false,name="lng") String language_id) {
if(language_id!=null && !language_id.equals(""))
user.language_id=language_id;
logger.info("user.id="+user.id+" user.name="+user.name+" user.language_id="+user.language_id+" user.country_id="+user.country_id);
boolean error=false;
String result="<metadata fn=\"-1\"><![CDATA[Request not processed!]]></metadata>";
String jspPath = context.getRealPath("/");
String db_url = "";
String db_login = "";
String db_password = "";
//Load DB configuration from "config.xml"
try {
String fullPath = context.getRealPath("/WEB-INF/config.xml");
File fXmlFile = new File(fullPath);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
Element nMain = doc.getDocumentElement();
NodeList nl = nMain.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
if (nl.item(i).getNodeName().equals("db-url"))
db_url = nl.item(i).getTextContent();
if (nl.item(i).getNodeName().equals("db-login"))
db_login = nl.item(i).getTextContent();
if (nl.item(i).getNodeName().equals("db-password"))
db_password = nl.item(i).getTextContent();
}
} catch (Exception ex) {
logger.info(ex.getMessage());
}
Connection conn = null;
try {
Class.forName("org.postgresql.Driver");
conn = DriverManager.getConnection(db_url, db_login, db_password);
if (conn != null) {
logger.info("Connect is OK!");
} else {
error=true;
result="<metadata fn=\"-1\"><![CDATA[An error occurred while connecting to the database!]]></metadata>";
}
} catch (Exception ex) {
logger.info(ex.getMessage());
error=true;
result="<metadata fn=\"-1\"><![CDATA[An error occurred while connecting to the database!]]></metadata>";
}
String fn="";
String treeid="";
String htmlid="";
//Парсим принятый XML запрос
InputStream body = new ByteArrayInputStream(reqData);
Document doc = null;
Element reqNode = null;
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(body);
} catch (Exception ex) {
logger.info(ex.getMessage());
return "<metadata fn=\"-1\"><![CDATA[Parsing request error!]]></metadata>";
}
if (doc != null) {
reqNode = doc.getDocumentElement();
}
//Парсим XML из файла
Document objXMLDocument = null;
try {
File inputFile = new File(jspPath+"resources"+File.separator+"engine/tree.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
objXMLDocument = dBuilder.parse(inputFile);
} catch (Exception ex) {
logger.info(ex.getMessage());
error=true;
}
Node mainNode=null;
//находим нужный узел в tree.xml для того чтобы выполнить запрос
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
if (doc != null) {
Object exprResult=null;
try {
XPathExpression expr = xpath.compile("//metadata/type[@id='" + treeid + "']");
exprResult = expr.evaluate(doc, XPathConstants.NODESET);
} catch (XPathExpressionException ex) {
logger.info(ex.getMessage());
}
NodeList nodeList = (NodeList) exprResult;
if (nodeList.getLength() > 0)
mainNode = nodeList.item(0);
}
String retrez="";
if(mainNode!=null)
{
//перебераем все дочерние элементы и для каждого выполняем запрос c фильтрацией
Node currNode = mainNode.getFirstChild(); //из tree.xml
while (currNode != null)
{
Node tmpNode=currNode; //если узел goto
if (tmpNode.getNodeName().equals("goto")) //если встретилась "зацикливалка"
{
treeid = tmpNode.getAttributes().getNamedItem("id").getNodeValue();
tmpNode=XMLTools.findFirstNodeOnAttribute(objXMLDocument.getDocumentElement(),"type","id",treeid);
if(tmpNode==null) { currNode = currNode.getNextSibling(); continue; }
}
if(tmpNode.getNodeName().equals("type")) //если выборка из базы
{
treeid=tmpNode.getAttributes().getNamedItem("id").getNodeValue();
String caption=tmpNode.getAttributes().getNamedItem("c").getNodeValue();
//j=0;
XMLTools.applyNodeToNode(reqNode,tmpNode,"n");
//Переносим значения в SQL запрос из фильтра
String sql=XMLTools.getCDATAValue(XMLTools.findNode(tmpNode,"sql-query"));
Node nFs=XMLTools.findNode(tmpNode, "filter");
if(nFs!=null)
{
Node nF=nFs.getFirstChild();
while(nF != null)
{
if(nF.getNodeName().equals("column"))
{
String vt = nF.getAttributes().getNamedItem("vt").getNodeValue();
String val= XMLTools.getCDATAValue(nF);
sql = sql.replace("${" + nF.getAttributes().getNamedItem("n").getNodeValue() + "}", Tools.getSQLValue(vt, val));
}
nF=nF.getNextSibling();
}
}
//Выполняем подготовленный SQL
Statement stmt;
ResultSet rs=null;
try {
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery(sql);
} catch (SQLException e) {
e.printStackTrace();
}
//res=fnGetData(reqNode,tmpNode);//currNode из tree.xml
if(rs==null)
{
//sendError('fnGetData==null!');
}else
{
try {
while (rs.next()) //while (row = res->fetch(PDO::FETCH_ASSOC))
{
String fid="";
String iid="";
String val="";
if(Tools.hasColumn(rs,"id")) fid=rs.getString("id"); else fid=""; //Уникальный id записи
if(Tools.hasColumn(rs,"icon_id")) iid=rs.getString("icon_id"); else iid=""; //id значка
if(Tools.hasColumn(rs,caption)) val=rs.getString(caption); else val=""; //Заголовок
String visible = "";
if(tmpNode.getAttributes().getNamedItem("visible").getNodeValue().equals("0")) visible=" visible=\"0\" ";
//Для проверки есть ли дети составляем XML запрос и отправляем в вункцию как будто он пришел от клиента
//c - Есть ли под узлы по умолчанию есть
//fid - id записи
//iid - id иконки
//treeid - id ветки дерева
//ObjectID - название поля с уникальным идентификатором записи
String xmlnode = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
xmlnode+="<tree c=\"1\" fid=\""+fid+"\" iid=\""+iid+"\" treeid=\""+treeid+"\" t=\""+tmpNode.getAttributes().getNamedItem("n").getNodeValue()+"\" ObjectID=\""+tmpNode.getAttributes().getNamedItem("ObjectID").getNodeValue()+"\""+visible+">";
xmlnode+="<![CDATA["+val+"]]>";
//сохраняем параметры фильтра для дочерних элементов с текщем состоянием
//перебираем фильтры которые должны быть заполненны для каждого узла даные для фильтра беруться из результ сета
xmlnode+="<columns>";
//считываем название поля и находим данные в результсете
Node nodeParam = XMLTools.findFirstNode(tmpNode, "columns"); //tree.xml
if(nodeParam!=null) nodeParam=nodeParam.getFirstChild();
while (nodeParam != null)
{
if(nodeParam.getNodeName().equals("param"))
{
String fname = nodeParam.getAttributes().getNamedItem("n").getNodeValue();
String fval="";
try
{
if(Tools.hasColumn(rs,fname))
{
fval=rs.getString(fname);
}else
{ fval=XMLTools.getCDATAValue(nodeParam);
}
} catch (Exception e)
{
//sendError(e->getMessage());
}
xmlnode+="<param n=\""+fname+"\"><![CDATA["+fval+"]]></param>";
}
nodeParam = nodeParam.getNextSibling();
}
xmlnode+="</columns>";
xmlnode+="</tree>";
//парсим созданную ветку дерева в DOMDocument потом посылаем в функцию взятия данных как будто их все открыли
//если есть данные то у этого узла дерева есть дети c="1" инече нет c="0".
int child = 0;
Document objXMLDocTree=null;
try
{ //objXMLDocTree->loadXML(xmlnode);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
objXMLDocument = dBuilder.parse(xmlnode);
} catch (Exception e)
{ //sendError(e->getMessage());
}
Element testNodeTree = objXMLDocTree.getDocumentElement();
Node testNode = tmpNode.getFirstChild(); //Текущий узел из tree.xml
while (testNode != null)
{
Node tmpNode2 = testNode;
if(tmpNode2.getNodeName().equals("goto"))
{
treeid=tmpNode2.getAttributes().getNamedItem("id").getNodeValue();
tmpNode2=XMLTools.findFirstNodeOnAttribute(objXMLDocument.getDocumentElement(),"type","id",treeid);
if(tmpNode2==null) { testNode = testNode.getNextSibling(); continue; }
}
if(tmpNode2.getNodeName().equals("type"))
{
/*Object testrs = fnGetData(conn,testNodeTree,tmpNode2);
if((testrs!=null)&&(testrs.rowCount()>0))
{
child=1;
break;
}*/
}
testNode = testNode.getNextSibling();
}
//testNodeTree.getAttribute("c",child);
//retrez+=objXMLDocTree->saveXML(objXMLDocTree.getDocumentElement());
//Закончили проверку на детей
}
} catch (DOMException | SQLException e) {
e.printStackTrace();
}
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
currNode = currNode.getNextSibling();
}
}else
{
result="<metadata fn=\"-1\"><![CDATA[Not find find id=\""+treeid+"\"!]]></metadata>";
}
result="<?xml version=\"1.0\" encoding=\"utf-8\"?><metadata fn=\"1\" htmlid=\""+htmlid+"\">"+retrez+"</metadata>";
//header('Content-type: text/xml');
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
//return body content
return result;
}
//Replace all the values of the first filter values from the second
public void setFilter(Node n1, Node n2) {
if (n1 == null || n2 == null)
return;
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
Node nc1 = n1.getFirstChild();
while (nc1 != null) {
if (nc1.getNodeName().equals("column")) {
try {
String path = "column[@n='" + nc1.getAttributes().getNamedItem("n").getNodeValue() + "']";
XPathExpression expr = xpath.compile(path);
NodeList nodeList = (NodeList) expr.evaluate(n2, XPathConstants.NODESET);
if (nodeList.getLength() > 0) {
Node nc2 = nodeList.item(0);
XMLTools.setCharacterDataToElement((Element) nc1, XMLTools.getCharacterDataFromElement((Element) nc2));
//getCdata($nc1)->nodeValue=getCdata($nc2)->nodeValue;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
//String message = "XML parsing error!";
//return;
}
}
nc1 = nc1.getNextSibling();
}
}
public ResultSet fnGetData(Connection conn,Node treeNode,Node currNode)
{
String sql=getSQL(treeNode,currNode);
/*if(gettype($_SESSION['USER_ID'])=='string')
sql=str_replace('${_user_id}',$_SESSION['USER_ID']=='' ? 'null' : '\''.$_SESSION['USER_ID'].'\'',$sql);
else
sql=str_replace('${_user_id}',$_SESSION['USER_ID']=='' ? 'null' : $_SESSION['USER_ID'],$sql);*/
Statement stmt;
ResultSet rs=null;
try {
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
/** Перенести параметры из родительского в sql строку дочернего элемента
* @param XMLNode $nParent Родительский узел
* @param XMLNode $nChild Дочерний узел
* @result Строка
*/
public String getSQL(Node nParent,Node nChild)
{
if(nChild==null) return "";
String sql="";
Node nPs=XMLTools.findNode(nParent, "columns");
Node nFs=XMLTools.findNode(nChild, "filter");
//Переносим значения в фильтр
if(nFs!=null)
{
Node nP;
if(nPs!=null) nP=nPs.getFirstChild(); else nP=null;
while (nP != null)
{
if (nP.getNodeName().equals("param"))
{
String val=XMLTools.getCDATAValue(nP);
Node nF=XMLTools.findNodeOnAttribute(nFs, "column", "pn", nP.getAttributes().getNamedItem("n").getNodeValue());
if(nF!=null)
XMLTools.setCharacterDataToElement(nF, val);
}
nP = nP.getNextSibling();
}
}
//Переносим значения в SQL запрос из фильтра
sql=XMLTools.getCDATAValue(XMLTools.findNode(nChild,"sql-query"));
nFs=XMLTools.findNode(nChild, "filter");
if(nFs!=null)
{ Node nF = nFs.getFirstChild();
while(nF != null)
{
if(nF.getNodeName().equals("column"))
{
sql = sql.replace("{"+nF.getAttributes().getNamedItem("n").getNodeValue()+"}", Tools.getSQLValue(nF.getAttributes().getNamedItem("vt").getNodeValue(),XMLTools.getCDATAValue(nF)));
}
nF=nF.getNextSibling();
}
}
return sql;
}
@Override
public void setServletContext(ServletContext servletContext) {
this.context=servletContext;
}
}

View File

@ -564,8 +564,9 @@ class EdtRec
input.setAttribute("id","prop_"+this.uid+"_"+nodeProp.getAttribute("n")+"_visible");
input.setAttribute("value","");
newCell1.appendChild(input);
//The hidden field where the data is saved (you can make it stored in XML)
var hidden = document.createElement('hidden');
//The hidden field where the data is saved (you can make it stored in XML)_
let hidden = document.createElement('input');
hidden.setAttribute("type", "hidden");
hidden.setAttribute("id","prop_"+this.uid+"_"+nodeProp.getAttribute("n"));
hidden.value=value;
newCell1.appendChild(hidden);
@ -890,10 +891,12 @@ class EdtRec
rec.f_TypeName=typeName;
rec.win.setLeftTop(pageX-250,pageY-10);
rec.win.setParent(this.win);
if(rec.request.callServer(ScriptName,'<?xml version="1.0" encoding="utf-8"?><metadata fn="0"><type n="'+rec.f_TypeName+'"></type></metadata>'))
rec.callData(rec.f_TypeName,"");
/*if(rec.request.callServer(ScriptName,'<?xml version="1.0" encoding="utf-8"?><metadata fn="0"><type n="'+rec.f_TypeName+'"></type></metadata>'))
{
rec.showProgressBar();
}
}*/
}
//Call the ShowRecord.html window with the parameters for the filter (not just the object name).
@ -919,7 +922,7 @@ class EdtRec
if(sub2==null) break;
var val=BeforeFirst(AfterFirst(xmlString,"${"),"}");
obj=document.getElementById("prop_"+this.uid+"_"+val);
let obj=document.getElementById("prop_"+this.uid+"_"+val);
if(obj!=null){
xmlString=sub1+obj.value+sub2;
}else{

View File

@ -385,13 +385,13 @@ class SRec
//we pass the id to the object filter prop_id - the name of the filter
setFilterObject(TypeName, prop_id, id)
{
node=findFirstNodeOnAttribute(this.nodeMetadata,'column','n',prop_id);
let node=findFirstNodeOnAttribute(this.nodeMetadata,'column','n',prop_id);
if(node!=null)
{
let name=node.getAttribute("FieldCaption");
getCdata(node).nodeValue=id;
//we request data from the server to fill in the comments on the record id
prop=document.getElementById('filter_'+this.uid+'_'+prop_id);
let prop=document.getElementById('filter_'+this.uid+'_'+prop_id);
if(prop!=null) prop.value=id;
//request comment on the id of the record from the server
if(this.request.callServer(ScriptName,'<?xml version="1.0" encoding="utf-8"?><metadata fn="6"><type n="'+TypeName+'" c="'+name+'" pn="'+prop_id+'" fn="'+name+'"><objects-list><filter><column n="id"><![CDATA['+id+']]></column></filter></objects-list></type></metadata>',true))
@ -487,7 +487,8 @@ class SRec
setMetadata(node)
{
this.nodeMetadata=node;
this.setXMLSettings(this.f_Settings); //Appending settings to nodeMetadata
//Create GUI filter
let td,tr,td1,td2;
let nodeFilter=null;
@ -507,9 +508,7 @@ class SRec
this.nodeMetadataObjList=findNode(nodeType, "objects-list");
if(this.win!=null) this.win.setWidth(this.nodeMetadataObjList.getAttribute("width"));
nodeFilter=findNodeOnPath(nodeType,"objects-list/filter");
//Appending settings to nodeMetadata
this.setXMLSettings(this.f_Settings);
//let id=-1;
//After loading the metadata, we request the data by sending an XML filter.
@ -853,13 +852,14 @@ class SRec
input.setAttribute("value","");
newCell1.appendChild(input);
//A hidden field where data is stored (you can make it stored in XML).
hidden = document.createElement('hidden');
let hidden = document.createElement('input');
hidden.setAttribute("type", "hidden");
hidden.setAttribute("id",'filter_'+this.uid+'_'+columnNode.getAttribute("n"));
//hidden.setAttribute("value",value)
hidden.value=value;
newCell1.appendChild(hidden);
button = document.createElement('input');
let button = document.createElement('input');
button.setAttribute("type","button");
button.setAttribute("value","...");
button.style.cssText="width:30px; height:100%;margin: 0px; padding: 0px;";

View File

@ -50,9 +50,9 @@ String.prototype.stripTags = function() {
};
//Показать прогрес бар
function showProgressBar(obj,img)
function showProgressBar(obj,img_id)
{
if(img === undefined) img='';
if(img_id === undefined) img_id='';
if (typeof obj === 'string' || obj instanceof String)
obj=document.getElementById(obj);
@ -61,7 +61,7 @@ function showProgressBar(obj,img)
let pBarDiv=document.createElement('div');
pBarDiv.id=obj.id+'_pBar';
pBarDiv.style.cssText='position: absolute; left: 0px; top: 0px; z-index: 1; background-color: rgba(0,0,0,0.5); width:100%; height: 100%;';
pBarDiv.innerHTML='<table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0"><tr><td align="center" style="vertical-align: middle;"><img src="../resources/metadata/dbms/images/loading'+img+'.gif" alt=""></td></tr></table>';
pBarDiv.innerHTML='<table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0"><tr><td align="center" style="vertical-align: middle;"><img src="../resources/metadata/dbms/images/loading'+img_id+'.gif" alt=""></td></tr></table>';
obj.appendChild(pBarDiv);
};
@ -617,7 +617,9 @@ function findNodeOnAttribute(node, nodename,Attribute,val)
var n = node.firstChild;
while (n != null)
{
if((n.nodeName.toLowerCase()==nodename.toLowerCase())&&(n.getAttribute(Attribute)==val)) return n;
if((n.nodeName.toLowerCase()==nodename.toLowerCase())&&(n.getAttribute(Attribute)==val)) {
return n;
}
n=n.nextSibling;
}
return null;
@ -800,15 +802,15 @@ function applyNodeToNode(first, second, name)
var fn=first.firstChild;
while (fn !== null)
{
//alert("child="+fn.nodeName+" = "+getXMLNodeSerialisation(fn));
//alert(name+" "+fn.getAttribute("n"));
var sn=null;
if(fn.nodeName!=="#text" && fn.nodeName!=="#cdata-section" && fn.nodeName!=="#comment") //потому что для этих getAttribute вызывает ошибку
if(fn.nodeName!=="#text" && fn.nodeName!=="#cdata-section" && fn.nodeName!=="#comment"){ //потому что для этих getAttribute вызывает ошибку
sn=findNodeOnAttribute(second,fn.nodeName,name,fn.getAttribute(name));
}
if(sn!==null) //Если по имени атрибуту совпали узлы
{
//Переписываем значения атрибутов из первого второму, если их нет то создаём.
//Переписываем значения атрибутов из первого второму, если их нет то создаются автоматом
for(i=0;i<fn.attributes.length;i++)
{ sn.setAttribute(fn.attributes[i].nodeName,fn.attributes[i].value);
}
@ -821,11 +823,10 @@ function applyNodeToNode(first, second, name)
{
getCdata(second).nodeValue = fn.nodeValue;
}else
{
{
second.appendChild(fn.cloneNode(true));
}
}
fn=fn.nextSibling;
}
}
@ -900,7 +901,7 @@ class TRequest
if((node==null)||(node.getAttribute("fn")==null)) alert(_('Error')+"\n"+_('No_data')+"!\n"+xmlHttpRequest.responseText);
else
{
//alert("Принятый браузером XML=\n"+getXMLNodeSerialisation(node));
//alert("XML=\n"+getXMLNodeSerialisation(node));
var fn = node.getAttribute("fn");
if(this.winObj!=null)
{