责任链解析xml配置

<?xml version="1.0" encoding="UTF-8"?>
<root name="均值离散度校验规则">
	<sheet sheetName="交流变(配)电" sheetText="交流变(配)电" typeCol="gclx8">
		<col fieldKey="dtjg18" fieldText="技术参数_主变压器_单台价格(含税)(万元/台)"
			 conditionSameFieldKey="gzsbdy9,sbxsxs14,sbxsrzs15,dtrl17" sameFieldText="改造设备的电压等级,设备型式(相数),设备型式(绕组数),单台容量" projectType="gclx8==更换变压器"/>
		<col fieldKey="dtjg22" fieldText="技术参数_10kV柱上变压器_单台价格(含税)(万元/台)"
			 conditionSameFieldKey="gzsbdy9,sbxs19,dtrl21" sameFieldText="改造设备的电压等级,设备型式,单台容量" projectType="gclx8==更换10kV配电变压器"/>
		<col fieldKey="tdjghs26" fieldText="技术参数_10kV室内变压器_单台价格(含税)(万元/台)"
			 conditionSameFieldKey="gzsbdy9,sbxs23,dtrl25" sameFieldText="改造设备的电压等级,设备型式,单台容量" projectType="gclx8==更换10kV配电变压器"/>	
		<col fieldKey="dtjg30" fieldText="技术参数_10kV箱式变_单台价格(含税)(万元/台)"
			 conditionSameFieldKey="gzsbdy9,sbxs27,dtrl29" sameFieldText="改造设备的电压等级,设备型式,单台容量" projectType="gclx8==更换10kV配电变压器"/>			 		 
		<col fieldKey="dtjg34" fieldText="技术参数_10kV箱式变(仅更换变压器)_单台价格(含税)(万元/台)"
			 conditionSameFieldKey="gzsbdy9,sbxs31,dtrl33" sameFieldText="改造设备的电压等级,设备型式,单台容量" projectType="gclx8==更换10kV配电变压器"/>			 		 
		<col fieldKey="djhs42" fieldText="技术参数_断路器_单价(含税)(万元/台)"
			 conditionSameFieldKey="gzsbdy9,sbxs39" sameFieldText="改造设备的电压等级,设备型式" projectType="更换断路器"/>			 		 
		<col fieldKey="djhs49" fieldText="技术参数_隔离开关_单价(含税)(万元/台)"
			 conditionSameFieldKey="gzsbdy9,jgxszs46,jgxsjd47" sameFieldText="改造设备的电压等级,结构型式(柱式),结构型式(接地)" projectType="gclx8==更换隔离开关"/>			 		 
		<col fieldKey="djhs53" fieldText="技术参数_高压开关柜_单价(含税)(万元/台)"
			 conditionSameFieldKey="gzsbdy9,sbxs50,sfhdlq51" sameFieldText="改造设备的电压等级,设备型式,是否含断路器" projectType="gclx8==更换高压开关柜"/>			 		 
		<col fieldKey="djhsdx56" fieldText="技术参数_电流互感器_单价(含税)(万元/支(单相))"
			 conditionSameFieldKey="gzsbdy9,jgxs54" sameFieldText="改造设备的电压等级,结构型式" projectType="gclx8==更换电流互感器"/>			 		 
		<col fieldKey="djhsdx59" fieldText="技术参数_电压互感器_单价(含税)(万元/支(单相))"
			 conditionSameFieldKey="gzsbdy9,jgxs57" sameFieldText="改造设备的电压等级,结构型式" projectType="gclx8==更换电压互感器"/>			 		 
		<col fieldKey="djhs63" fieldText="技术参数_并联电容器_单价(含税)(万元/组)"
			 conditionSameFieldKey="gzsbdy9,jgxs60" sameFieldText="改造设备的电压等级,结构型式" projectType="gclx8==更换并联电容器"/>			 		 
		<col fieldKey="djhs65" fieldText="技术参数_避雷器_单价(含税)(万元/支)"
			 conditionSameFieldKey="gzsbdy9" sameFieldText="改造设备的电压等级" projectType="gclx8==更换避雷器"/>			 		 
		<!--<col fieldKey="jzgcf70" fieldText="竣工决算(万元)_建筑工程费"
			 conditionSameFieldKey="gclx8,gzsbdy9" sameFieldText="工程类型,改造设备的电压等级" projectType=""/>			 		 
		<col fieldKey="sbgzf71" fieldText="竣工决算(万元)_设备购置费"
			 conditionSameFieldKey="gclx8,gzsbdy9" sameFieldText="工程类型,改造设备的电压等级" projectType=""/>			 		 
		<col fieldKey="azgcfhj72" fieldText="竣工决算(万元)_安装工程费_安装工程费合计"
			 conditionSameFieldKey="gclx8,gzsbdy9" sameFieldText="工程类型,改造设备的电压等级" projectType=""/>			 		 
		<col fieldKey="ccgcf74" fieldText="竣工决算(万元)_拆除工程费"
			 conditionSameFieldKey="gclx8,gzsbdy9" sameFieldText="工程类型,改造设备的电压等级" projectType=""/>			 		 
		<col fieldKey="qtfyzj75" fieldText="竣工决算(万元)_其他费用_其他费用总计"
			 conditionSameFieldKey="gclx8,gzsbdy9" sameFieldText="工程类型,改造设备的电压等级" projectType=""/>-->			 		 
	</sheet>

	<!--<sheet sheetName="变电站全站综自改造" sheetText="变电站全站综自改造">		 		 
		<col fieldKey="jzgcf20" fieldText="决算_建筑工程费"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级(kV)" projectType=""/>			 		 
		<col fieldKey="sbgzf24" fieldText="决算_设备购置费"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级(kV)" projectType=""/>			 		 
		<col fieldKey="azgcfhj21" fieldText="决算_安装工程费_安装工程费合计"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级(kV)" projectType=""/>			 		 
		<col fieldKey="ccgcf23" fieldText="决算_拆除工程费"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级(kV)" projectType=""/>			 		 
		<col fieldKey="qtfyhj25" fieldText="决算_其他费用_其他费用总计"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级(kV)" projectType=""/>			 		 
	</sheet>-->	
	
	<sheet sheetName="交流继电保护" sheetText="交流继电保护" typeCol="gclx8">		 		 
		<col fieldKey="djhs16" fieldText="更换主变保护_单价(万元/套)(含税)"
			 conditionSameFieldKey="gzsbdy9,sbxs14" sameFieldText="改造设备的电压等级,设备型式" projectType="gclx8==更换主变保护"/>
		<col fieldKey="jj19" fieldText="更换主变保护_均价(万元)"
			 conditionSameFieldKey="gzsbdy9,sbxs14" sameFieldText="改造设备的电压等级,设备型式" projectType="gclx8==更换主变保护"/>
		<col fieldKey="gzslt21" fieldText="更换母差保护_改造数量(套)" formulaRealValue="sbgzf41/gzslt21"
			 conditionSameFieldKey="gzsbdy9" sameFieldText="改造设备的电压等级" projectType="gclx8==更换母差保护"/>
		<col fieldKey="jj24" fieldText="更换母差保护_均价(万元)" 
			 conditionSameFieldKey="gzsbdy9" sameFieldText="改造设备的电压等级" projectType="gclx8==更换母差保护"/>
		<col fieldKey="gzslt26" fieldText="更换线路保护_改造数量(套)"  formulaRealValue="sbgzf41/gzslt26"
			 conditionSameFieldKey="gzsbdy9" sameFieldText="改造设备的电压等级" projectType="gclx8==更换线路保护"/>
		<col fieldKey="jj29" fieldText="更换线路保护_均价(万元)" 
			 conditionSameFieldKey="gzsbdy9" sameFieldText="改造设备的电压等级" projectType="gclx8==更换线路保护"/>
		<col fieldKey="gzslt32" fieldText="更换母联或断路器保护_改造数量(套)"  formulaRealValue="sbgzf41/gzslt32"
			 conditionSameFieldKey="gzsbdy9" sameFieldText="改造设备的电压等级" projectType="gclx8==更换母联或断路器保护"/>
		<col fieldKey="jj35" fieldText="更换母联或断路器保护_均价(万元)" 
			 conditionSameFieldKey="gzsbdy9" sameFieldText="改造设备的电压等级" projectType="gclx8==更换母联或断路器保护"/>
		<!--<col fieldKey="jzgcf37" fieldText="决算_建筑工程费"
			 conditionSameFieldKey="gclx8,gzsbdy9" sameFieldText="工程类型,改造设备的电压等级(kV)" projectType=""/>			 		 
		<col fieldKey="sbgzf41" fieldText="决算_设备购置费"
			 conditionSameFieldKey="gclx8,gzsbdy9" sameFieldText="工程类型,改造设备的电压等级(kV)" projectType=""/>			 		 
		<col fieldKey="azgcfhj38" fieldText="决算_安装工程费_安装工程费合计"
			 conditionSameFieldKey="gclx8,gzsbdy9" sameFieldText="工程类型,改造设备的电压等级(kV)" projectType=""/>			 		 
		<col fieldKey="ccgcf40" fieldText="决算_拆除工程费"
			 conditionSameFieldKey="gclx8,gzsbdy9" sameFieldText="工程类型,改造设备的电压等级(kV)" projectType=""/>			 		 
		<col fieldKey="qtfyhj42" fieldText="决算_其他费用_其他费用总计"
			 conditionSameFieldKey="gclx8,gzsbdy9" sameFieldText="工程类型,改造设备的电压等级(kV)" projectType=""/>-->		 		 
	</sheet>	

	<sheet sheetName="交流输电" sheetText="交流输电" typeCol="gclx7">		 		 
		<col fieldKey="tcl21" fieldText="技术参数_改造杆塔_角钢塔_塔材量(t)" formulaRealValue="tcl21/tjs20"
			 conditionSameFieldKey="zxdydj8" sameFieldText="站、线电压等级(kV)" projectType="gclx7==更换杆塔(塔身)"/>			 		 
		<col fieldKey="tcjg22" fieldText="技术参数_改造杆塔_角钢塔_塔材价格(元/t)(含税)"
			 conditionSameFieldKey="zxdydj8" sameFieldText="站、线电压等级(kV)" projectType="gclx7==更换杆塔(塔身)"/>	
		<col fieldKey="tcl24" fieldText="技术参数_改造杆塔_钢管塔_塔材量(t)" formulaRealValue="tcl24/tjs23"
			 conditionSameFieldKey="zxdydj8" sameFieldText="站、线电压等级(kV)" projectType="gclx7==更换杆塔(塔身)"/>			 		 
		<col fieldKey="ggjg25" fieldText="技术参数_改造杆塔_钢管塔_钢管价格(元/t)(含税)"
			 conditionSameFieldKey="zxdydj8" sameFieldText="站、线电压等级(kV)" projectType="gclx7==更换杆塔(塔身)"/>				 		 		 
		<col fieldKey="jghs31" fieldText="技术参数_改造杆塔_水泥杆_价格(元/基)(含税)"
			 conditionSameFieldKey="zxdydj8,ggd30" sameFieldText="站、线电压等级(kV),技术参数_改造杆塔_水泥杆_杆高度(m)" projectType="gclx7==更换杆塔(塔身)"/>				 		 		 
		<col fieldKey="xcl37" fieldText="技术参数_导线_线材量(t)" formulaRealValue="xcl37/xlcdhjzd13"
			 conditionSameFieldKey="zxdydj8,dxcz33,dgdxjmj35" sameFieldText="站、线电压等级,导线材质,单根导线截面积" projectType="gclx7==更换导线"/>				 		 		 
		<col fieldKey="dxjg38" fieldText="技术参数_导线_导线价格(元/t)(含税)"
			 conditionSameFieldKey="zxdydj8,dxcz33,dgdxjmj35" sameFieldText="站、线电压等级,导线材质,单根导线截面积" projectType="gclx7==更换导线"/>				 		 		 
		<col fieldKey="xcl42" fieldText="技术参数_地线_线材量(t)" formulaRealValue="xcl42/xlcdhjzd13"
			 conditionSameFieldKey="zxdydj8,dxcz40,jmj39" sameFieldText="站、线电压等级,地线材质,截面积" projectType="gclx7==更换地线"/>				 		 		 
		<col fieldKey="dxhs43" fieldText="技术参数_地线_地线(价格元/t)(含税)"
			 conditionSameFieldKey="zxdydj8,dxcz40,jmj39" sameFieldText="站、线电压等级,地线材质,截面积" projectType="gclx7==更换地线"/>				 		 		 
		<col fieldKey="hcjyzzjjg55" fieldText="技术参数_绝缘子_合成绝缘子总价价格(万元)(含税)" formulaRealValue="hcjyzzjjg55/hcjyzgcl45"
			 conditionSameFieldKey="zxdydj8,jyzlx44" sameFieldText="站、线电压等级,绝缘子类型" projectType="gclx7==更换地线"/>				 		 		 
		<col fieldKey="psjyzzjjg57" fieldText="技术参数_绝缘子_盘式绝缘子总价价格(万元)(含税)" formulaRealValue="psjyzzjjg57/psjyzgcl56"
			 conditionSameFieldKey="zxdydj8,jyzlx44" sameFieldText="站、线电压等级,绝缘子类型" projectType="gclx7==更换地线"/>				 		 		 
		<col fieldKey="djhs61" fieldText="技术参数_线路避雷器_单价(万元/组)(含税)" 
			 conditionSameFieldKey="zxdydj8" sameFieldText="站、线电压等级" projectType="gclx7==更换避雷器"/>				 		 		 
		<col fieldKey="tsfl90" fieldText="技术参数_土石方量_m3" 
			 conditionSameFieldKey="zxdydj8" sameFieldText="站、线电压等级" projectType="gclx7==杆塔基础工程"/>				 		 		 
		<col fieldKey="hntlhj92" fieldText="技术参数_基础混凝土量_混凝土量合计"  formulaRealValue="hntlhj92/tjshj91"
			 conditionSameFieldKey="zxdydj8" sameFieldText="站、线电压等级" projectType="gclx7==杆塔基础工程"/>				 		 		 
		<col fieldKey="jcgcl109" fieldText="技术参数_基础钢材_基础钢材量(t)" 
			 conditionSameFieldKey="zxdydj8" sameFieldText="站、线电压等级" projectType="gclx7==杆塔基础工程"/>			 		 
		<col fieldKey="cldjhs110" fieldText="技术参数_基础钢材_材料单价(元/t)(含税)" 
			 conditionSameFieldKey="zxdydj8" sameFieldText="站、线电压等级" projectType="gclx7==杆塔基础工程"/>			 		 
		<!--<col fieldKey="jzgcf115" fieldText="竣工决算(万元)_建筑工程费"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级" projectType=""/>			
		<col fieldKey="ccgcf116" fieldText="竣工决算(万元)_拆除工程费"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级" projectType=""/>				 
		<col fieldKey="qtfyzj118" fieldText="竣工决算(万元)_其他费用_其他费用总计"
			 conditionSameFieldKey="zxdydj8" sameFieldText="工程类型,站、线电压等级" projectType=""/>	-->					 
	</sheet>	
	
	<sheet sheetName="通信工程" sheetText="通信工程" typeCol="gclx7">		 		 
		<col fieldKey="gzslt14" fieldText="光端机_改造数量(套)" formulaRealValue="sbgzf21/gzslt14"
			 conditionSameFieldKey="zxdydj8,rl13" sameFieldText="站、线电压等级(kV),容量" projectType="gclx7==更换光端机"/>		
		<col fieldKey="gzslt16" fieldText="会议电视终端_改造数量(套)" formulaRealValue="sbgzf21/gzslt16"
			 conditionSameFieldKey="zxdydj8,zdrl15" sameFieldText="站、线电压等级(kV),终端容量" projectType="gclx7==更换会议电视终端"/>		
		<!--<col fieldKey="jzgcf17" fieldText="决算_建筑工程费"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级(kV)" projectType=""/>			 		 
		<col fieldKey="sbgzf21" fieldText="决算_设备购置费"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级(kV)" projectType=""/>			 		 
		<col fieldKey="azgcfhj18" fieldText="决算_安装工程费_安装工程费合计"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级(kV)" projectType=""/>			 		 
		<col fieldKey="ccgcf20" fieldText="决算_拆除工程费"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级(kV)" projectType=""/>			 		 
		<col fieldKey="qtfyhj22" fieldText="决算_其他费用_其他费用总计"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级(kV)" projectType=""/>-->					 
	</sheet>		

	<sheet sheetName="通信光缆" sheetText="通信光缆" typeCol="gclx7">		 		 
		<col fieldKey="xcl16" fieldText="技术参数_线材量(t)" formulaRealValue="xcl16/xlcd15"
			 conditionSameFieldKey="gclx7,zxdydj8,sbxh13,xs14" sameFieldText="工程类型,站、线电压等级,设备型号,芯数" projectType=""/>		
		<col fieldKey="gljg17" fieldText="技术参数_光缆价格(元/km)(含税)"
			 conditionSameFieldKey="zxdydj8,sbxh13,xs14" sameFieldText="站、线电压等级,设备型号,芯数" projectType=""/>		
		<!--<col fieldKey="jzgcf18" fieldText="竣工决算(万元)_建筑工程费"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级" projectType=""/>			 		 		 		 
		<col fieldKey="azgcf19" fieldText="竣工决算(万元)_安装工程费(万元)"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级" projectType=""/>			 		 
		<col fieldKey="ccgcf20" fieldText="竣工决算(万元)_拆除工程费"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级" projectType=""/>			 		 
		<col fieldKey="qtfyzj22" fieldText="竣工决算(万元)_其他费用_其他费用总计"
			 conditionSameFieldKey="gclx7,zxdydj8" sameFieldText="工程类型,站、线电压等级" projectType=""/>-->		
	</sheet>		

	<sheet sheetName="调度自动化系统" sheetText="调度自动化系统" typeCol="gclx7">		 		 
		<col fieldKey="dj19" fieldText="调度数据网_核心节点_单价(万元/个)"
			 conditionSameFieldKey="gclx7,jb16" sameFieldText="工程类型,级别" projectType="gclx7==改造调度数据网"/>		
		<col fieldKey="pmdj132" fieldText="调度大屏幕系统_屏幕参数及数量_规格1_屏幕单价(万元/块)"
			 conditionSameFieldKey="gclx7,pulx26" sameFieldText="工程类型,屏幕类型" projectType="gclx7==改造调度大屏幕系统"/>		
		<!--<col fieldKey="jzgcf39" fieldText="决算_建筑工程费"
			 conditionSameFieldKey="gclx7" sameFieldText="工程类型" projectType=""/>			 		 
		<col fieldKey="azgcfhj21" fieldText="决算_安装工程费_安装工程费合计"
			 conditionSameFieldKey="gclx7" sameFieldText="工程类型" projectType=""/>			 		 
		<col fieldKey="ccgcf42" fieldText="决算_拆除工程费"
			 conditionSameFieldKey="gclx7" sameFieldText="工程类型" projectType=""/>			 		 
		<col fieldKey="sbgzf24" fieldText="决算_设备购置费_合计"
			 conditionSameFieldKey="gclx7" sameFieldText="工程类型" projectType=""/>			 		 
		<col fieldKey="qtfyhj46" fieldText="决算_其他费用_其他费用总计"
			 conditionSameFieldKey="gclx7" sameFieldText="工程类型" projectType=""/>	-->			

	</sheet>		
	
	
</root>
package com.booway.zjfx.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

import com.booway.common.Func;

public class DispersionMeasureUtil extends HashMap<String, Object>
{
    private static final long serialVersionUID = 1L;

    private List<DispersionMeasureUtil> dispersions = new ArrayList<DispersionMeasureUtil>();

    private String sheetName;

    //对应工程类型字段
    private String projectTypeCol;

    private Element element;

    private DispersionMeasureUtil parent;

    public DispersionMeasureUtil(DispersionMeasureUtil parent, Element element)
    {
        this.element = element;
        this.parent = parent;
        this.sheetName = element.getNodeName();
    }

    public DispersionMeasureUtil(Element element)
    {
        this.element = element;
        this.sheetName = element.getNodeName();
    }

    public List<DispersionMeasureUtil> getDispersions()
    {
        return dispersions;
    }

    public void setDispersions(List<DispersionMeasureUtil> dispersions)
    {
        dispersions = this.dispersions;
    }

    public String getSheetName()
    {
        return sheetName;
    }

    public void parse()
    {
        if (null != element)
        {
            NamedNodeMap nodeMap = element.getAttributes();
            Node node;
            Node childNode;
            Element childEle;
            DispersionMeasureUtil child;
            for (int i = 0; i < nodeMap.getLength(); i++)
            {
                node = nodeMap.item(i);
                if (!Func.checkNullOrEmpty(node.getNodeName()))
                {
                    put(node.getNodeName(), node.getNodeValue());
                }
            }

            if (element.hasChildNodes())
            {
                for (int j = 0; j < element.getChildNodes().getLength(); j++)
                {
                    childNode = element.getChildNodes().item(j);
                    if (childNode.getNodeType() == Element.ELEMENT_NODE)
                    {
                        childEle = (Element) childNode;
                        child = new DispersionMeasureUtil(this, childEle);
                        child.parse();
                    }
                }
            }
            if (this.parent != null)
            {
                this.parent.getDispersions().add(this);
            }

        }
    }

    public static List<DispersionMeasureUtil> getSheetNameEle(DispersionMeasureUtil info, String nodeName)
    {
        if (info == null)
        {
            return new ArrayList<DispersionMeasureUtil>();
        }

        List<DispersionMeasureUtil> result = new ArrayList<DispersionMeasureUtil>();
        List<DispersionMeasureUtil> childDispersions;
        if (info.getSheetName().equals(nodeName))
        {
            result.add(info);
            return result;
        } else
        {
            childDispersions = info.getDispersions();
            for (int i = 0; i < childDispersions.size(); i++)
            {
                result.addAll(getSheetNameEle(childDispersions.get(i), nodeName));
            }
        }

        return result;
    }

    /**
     * 获取需要校验的sheetName页签和fieldKey字段。
     * @param disList 表示所有有页签
     * @param sheetName 表示要需要获取的页签名称
     * @param fieldKey 表示需要获取的字段
     * @return 返回数据
     * @throws Exception 异常
     */
    public static DispersionMeasureUtil getDespersionBySheetName(List<DispersionMeasureUtil> disList, String sheetName,
            String fieldKey) throws Exception
    {
        if (disList == null || disList.size() <= 0 || Func.checkNullOrEmpty(sheetName)
                || Func.checkNullOrEmpty(fieldKey))
        {
            return null;
        }
        for (DispersionMeasureUtil dis : disList)
        {
            if (sheetName.equals(dis.get("sheetName")))
            {
                for (DispersionMeasureUtil d : dis.getDispersions())
                {
                    if (fieldKey.equals(d.get("fieldKey")))
                    {
                        return d;
                    }
                }
            }
        }
        return null;
    }

    public String getProjectTypeCol()
    {
        this.projectTypeCol = Func.parseStr(this.get("typeCol"));
        return projectTypeCol;
    }

}
package com.booway.zjfx.check.util;

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

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

import com.booway.hbjg.data.DataColumn;
import com.booway.hbjg.data.DataColumnCollection;
import com.booway.hbjg.data.DataRow;
import com.booway.hbjg.data.DataRowCollection;
import com.booway.hbjg.data.DataTable;
import com.booway.hbjg.util.DataTableUtil;
import com.booway.hbjg.util.Func;
import com.booway.zjfx.check.entity.Tempformula;
import com.booway.zjfx.check.entity.ZjfxcheckDispersion;
import com.booway.zjfx.tablehead.po.ColumnHead;
import com.booway.zjfx.util.Const;
import com.booway.zjfx.util.DispersionMeasureUtil;
import com.booway.zjfx.util.FelUtil;
import com.booway.zjfx.util.ValidContext;
import com.greenpineyu.fel.FelEngine;
import com.greenpineyu.fel.FelEngineImpl;
import com.greenpineyu.fel.context.FelContext;
import com.greenpineyu.fel.parser.FelNode;

/**
 * @author fanjun
 * 均值离散度校验
 */
public class ZjfxcheckDispersionUntil
{
    private ZjfxcheckDispersionUntil()
    {

    }

    /**
     * 加入均值离散度信息
     * @param tem
     * @param validContext
     */
    public static void putCheckDisperInfo(Tempformula tem, ValidContext validContext)
    {
        if (tem != null && tem.getCheckTypeStr().indexOf(CheckConstants.DISPER) >= 0)
        {
            validContext.setCheckDisper(true);
            validContext.setRegion(Func.parseDbl(tem.getFz()));
        }
    }

    public static List<DispersionMeasureUtil> sheetMap = new ArrayList<DispersionMeasureUtil>();
    // 用于解析
    public static String eleName = "sheet";
    public static String projectType = "projectType";
    public static String conditionSameFieldKey = "conditionSameFieldKey";
    public static String formulaRealValue = "formulaRealValue";
    public static final int ACCURACY = 6;

    private static void getDeispersionMeasure() throws Exception
    {
        InputStream in = new FileInputStream(Const.DISPERSION_PATH);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();

        Document doc = builder.parse(in);
        doc.normalize();
        DispersionMeasureUtil info = new DispersionMeasureUtil(null, doc.getDocumentElement());
        info.parse();
        sheetMap = DispersionMeasureUtil.getSheetNameEle(info, eleName);
    }

    /**
     * 单个字段校验均值离散度(数据库已保存的均值)
     * @param dispers 工程所有的均值离散度值
     * @param fieldname 字段名称
     * @param value 校验值
     * @param region 阀值
     * @return 错误信息
     */
    public static String checkDispersiion(Map<String, Double> dispers, String fieldname, double value, double region)
    {
        if (dispers.containsKey(fieldname))
        {
            double avg = dispers.get(fieldname);
            double min = avg * (1 - region);
            double max = avg * (1 + region);
            if (!(min < value && max > value))
            {
                return "均值离散度超出区间范围,校验参数【均值:" + avg + "】【阀值:" + region + "】";
            }
        }
        return "";
    }

    /**
     * 均值离散度校验(实时计算离散度)
     * @param tempHead 当前单元格的校验规则
     * @param cellValue 当前单元格的数值
     * @param rowValueMap 当前行数据
     * @param allRowValueMap 当前页签的所有行数据
     * @param sheetName 页签名称
     * @return 返回数据
     * @throws Exception 异常
     */
    public static String checkDispersionMeasure(ValidContext validContext, String cellValue, String fieldname)
            throws Exception
    {
        if (Func.checkNullOrEmpty(cellValue))
        {
            return null;
        }
        if (sheetMap == null || sheetMap.size() <= 0)
        {
            getDeispersionMeasure();
        }
        String sheetName = validContext.getSheetname();
        // 根据页签和字段名称(“sheetName”,“fieldKey”)来获取当前单元格的离散度的校验规则
        DispersionMeasureUtil dis = DispersionMeasureUtil.getDespersionBySheetName(sheetMap, sheetName, fieldname);
        if (dis == null)
        {
            return null;
        }
        Map<String, Object> rowValueMap = validContext.getRowValueMap();
        List<Map<String, Object>> allRowValueMap = validContext.getAllRowValueMap();
        String prjType = Func.parseStr(dis.get(projectType));

        String[] conditionKey = Func.parseStr(dis.get(conditionSameFieldKey)).split(",");
        String formulaValue = Func.parseStr(dis.get(formulaRealValue));
        if (!haveDoDisperCheck(conditionKey, rowValueMap))
        {
            return null;
        }
        // 表示过滤的数据。 即通过离散度相同字段相同数据进行过滤
        List<Map<String, Object>> filterData = new ArrayList<>();
        filterData = filterDataResult(allRowValueMap, rowValueMap, conditionKey, prjType);

        if (filterData.size() <= 0)
        {
            return null;
        }

        double filterValue = 0d;
        double meanValue = 0d;
        double currentValue = 0d;
        // 此处,进行判断,当前进行统计的离散度是否是一个公式。   “formulaValue”为空时表示不是公式, 如果不为空,则将公式计算结果作为统计值。
        if (Func.checkNullOrEmpty(formulaValue))
        {
            int num = 0;
            for (Map<String, Object> map : filterData)
            {
                if (Func.isNumStr(Func.parseStr(map.get(fieldname))))
                {
                    num++;
                    filterValue += Func.parseDbl(map.get(fieldname));
                }
            }
            // 获取过滤后数据的平均值
            meanValue = Func.parseDbl(filterValue / num, ACCURACY);
            currentValue = Func.parseDbl(cellValue, ACCURACY);
        } else
        {
            // 使用fel,进行动态将每次数据进行公式计算,并且累加
            FelEngine fel = new FelEngineImpl();
            FelNode felNode = fel.parse(formulaValue);
            FelContext ctx = null;

            for (Map<String, Object> map : filterData)
            {
                filterValue += calFormulaValue(map, fel, ctx, felNode);
            }
            // 获取过滤后数据的平均值
            meanValue = Func.parseDbl(filterValue / filterData.size(), ACCURACY);

            currentValue = calFormulaValue(rowValueMap, fel, ctx, felNode);
        }
        //添加均值离散度对象
        List<ZjfxcheckDispersion> dispersionList = validContext.getDispersion();
        if (dispersionList != null)
        {
            ZjfxcheckDispersion disper = new ZjfxcheckDispersion();
            disper.setFormual(formulaValue);
            disper.setAvg(Func.isNumber(meanValue) ? meanValue : 0d);
            disper.setColumname(fieldname);
            disper.setProjectid(validContext.getProjectId());
            disper.setId(Func.newGuid());
            disper.setSheetName(sheetName);
            disper.setVersionId(validContext.getZjfxId());
            dispersionList.add(disper);
        }

        // 根据离散度阀值默认值,进行配对,是否满足. 
        if (!(meanValue * (1 - validContext.getRegion()) <= Func.parseDbl(currentValue, ACCURACY) && Func.parseDbl(
                currentValue, ACCURACY) <= meanValue * (1 + validContext.getRegion())))
        {
            return "△.请填写相符数据,并且数值范围符合当前数据的离散度之间!【均值:" + Func.parseDbl(meanValue) + "阀值:" + validContext.getRegion()
                    + "】";
        }
        return null;
    }

    /**
     * 是否需要做离散度校验(只有当所有的筛选字段值都不为空的时候才做校验)
     * @param rowValueMap 工程数据
     * @param conditionKey 筛选字段
     * @return
     */
    private static boolean haveDoDisperCheck(String[] conditionKey, Map<String, Object> rowValueMap)
    {
        boolean flag = true;
        for (String string : conditionKey)
        {
            if (Func.checkNullOrEmpty(rowValueMap.get(string)))
            {
                flag = false;
            }
        }
        return flag;

    }

    /**
     * 均值离散度校验(利用数据库中缓存的离散度校验)
     * @param tempHead 当前单元格的校验规则(不含均值离散度),
     * @param cellValue 当前单元格的数值
     * @param rowValueMap 当前行数据
     * @param allRowValueMap 当前页签的所有行数据
     * @param sheetName 页签名称
     * @return 返回数据
     * @throws Exception 异常
     */
    public static String checkDispersionMeasureWithDisper(Map<String, ZjfxcheckDispersion> dismap,
            ValidContext validContext, String cellValue) throws Exception
    {
        if (Func.checkNullOrEmpty(cellValue) || dismap == null || dismap.isEmpty())
        {
            return null;
        }
        ColumnHead tempHead = validContext.getColumnHead();
        //区间
        double region = validContext.getRegion();
        String fieldname = tempHead.getFieldName();
        if (dismap.get(fieldname) == null)
        {
            return null;
        }
        ZjfxcheckDispersion disper = dismap.get(fieldname);
        String formuall = disper.getFormual();
        double meanValue = disper.getAvg();
        double checkValue = Func.parseDbl(cellValue, ACCURACY);
        if (!Func.checkNullOrEmpty(formuall))
        { // 使用fel,进行动态将每次数据进行公式计算,并且累加
            FelEngine fel = new FelEngineImpl();
            FelNode felNode = fel.parse(formuall);
            FelContext ctx = null;
            Map<String, Object> rowValue = validContext.getRowValueMap();
            checkValue = calFormulaValue(rowValue, fel, ctx, felNode);
        }

        // 根据离散度阀值默认值,进行配对,是否满足. 
        if (!(meanValue * (1 - region) <= checkValue && checkValue <= meanValue * (1 + region)))
        {
            String msg = "△.请填写相符数据,并且数值范围符合当前数据的离散度之间!【均值:" + meanValue + "阀值:" + region + "】";
            /*   if (!Func.checkNullOrEmpty(formuall))
               {
                   msg += "【计算公式:" + formuall + "】";
               }*/
            return msg;
        }
        return null;
    }

    /**
     * 将fel计算进行封装,计算出结果.
     * @param rowValueMap
     * @param fel
     * @param ctx
     * @param felNode
     * @return
     * @throws Exception
     */
    private static double calFormulaValue(Map<String, Object> rowValueMap, FelEngine fel, FelContext ctx,
            FelNode felNode) throws Exception
    {
        // 使用fel进行求出,当前单元格的数据行,的公式计算结果。(即需要对比的数据)
        ctx = fel.getContext();
        FelUtil.setFelContextValue(rowValueMap, ctx);
        /*   if (!FelUtil.checkFormula(felNode, ctx))
           {
               throw new Exception("校验离散度失败,未获取到公式数据!");
           }*/
        return Func.parseDbl(FelUtil.getFormulaValue(felNode, ctx), ACCURACY);
    }

    /**
     * 通过配置文件当中的字段,进行数据的过滤。
     * @param allRowValueMap 所有的数据
     * @param rowValueMap 当前行的数据
     * @param conditionKey 要过滤的字段
     * @param prjType 特殊工程
     * @return 返回要进行离散度数据统计的数据集合
     * @throws Exception 异常
     */
    private static List<Map<String, Object>> filterDataResult(List<Map<String, Object>> allRowValueMap,
            Map<String, Object> rowValueMap, String[] conditionKey, String prjType) throws Exception
    {
        if (allRowValueMap.size() <= 0 || rowValueMap.isEmpty())
        {
            return new ArrayList<Map<String, Object>>();
        }

        List<Map<String, Object>> filterData = new ArrayList<Map<String, Object>>();
        boolean flag = false;
        String[] prjTypeValue = null;
        for (Map<String, Object> rowMap : allRowValueMap)
        {
            flag = true;
            for (int i = 0; i < conditionKey.length; i++)
            {
                try
                {
                    // 遍历得到所有要过滤的字段,如果其中任何一个字段不等于当前行字段的值,则标记为false.跳过离散度的统计
                    if (!rowValueMap.get(conditionKey[i]).equals(rowMap.get(conditionKey[i])))
                    {
                        flag = false;
                    }
                } catch (Exception e)
                {
                    e.printStackTrace();
                }

            }
            if (!flag)
            {
                continue;
            }

            // 过滤特殊工程下的数据。
            if (!Func.checkNullOrEmpty(prjType))
            {
                prjTypeValue = prjType.split("==");
                if (prjTypeValue.length == 2 && !prjTypeValue[1].equals(rowMap.get(prjTypeValue[0])))
                {
                    continue;
                }
            }
            filterData.add(rowMap);
        }
        return filterData;
    }

    /**
     * 根据planid从数据库中取数据
     * @param planid 
     * @param tableName 数据库表名
     * @return
     */
    public static List<Map<String, Object>> getAllDataByPlanid(String planid, String tableName)
    {
        if (Func.checkNullOrEmpty(planid) || Func.checkNullOrEmpty(tableName))
        {
            return null;
        }
        String sql = "select * from " + tableName + " t where t.PLANID=?";
        DataTable tb = DataTableUtil.queryDataTableWithSqlClumToLowerCase(sql, tableName, new Object[]
        { planid });
        if (tb == null)
        {
            return null;
        }
        DataColumnCollection colums = tb.getColumns();
        DataRowCollection rows = tb.getRows();
        if (rows.isEmpty())
        {
            return null;
        }
        List<Map<String, Object>> allRowData = new ArrayList<Map<String, Object>>();
        for (DataRow r : rows)
        {
            Map<String, Object> rowdata = new HashMap<String, Object>();
            for (DataColumn col : colums)
            {
                rowdata.put(col.getColumnName(), r.getValue(col));
            }
            allRowData.add(rowdata);
        }
        return allRowData;
    }

    /**
     * 根据工程类型分组
     * @param allData 所有数据
     * @param col 工程类型字段
     * @return
     */
    public static Map<String, List<Map<String, Object>>> classIfyByProjectType(List<Map<String, Object>> allData,
            String col)
    {
        Map<String, List<Map<String, Object>>> alldataForMap = new HashMap<String, List<Map<String, Object>>>();
        if (allData == null || Func.checkNullOrEmpty(col))
        {
            return alldataForMap;
        }
        List<String> types = new ArrayList<String>();
        for (Map<String, Object> data : allData)
        {
            String type = Func.parseStr(data.get(col));
            if (!types.contains(type))
            {
                types.add(type);
            }
        }
        for (String tp : types)
        {
            if (Func.checkNullOrEmpty(tp))
            {
                continue;
            }
            List<Map<String, Object>> datas = new ArrayList<Map<String, Object>>();
            for (Map<String, Object> data : allData)
            {
                if (tp.equals(data.get(col)))
                {
                    datas.add(data);
                }
            }
            allData.removeAll(datas);
            alldataForMap.put(tp, datas);
        }
        return alldataForMap;
    }

    /**
     * 获取工程类型字段
     * @param disList
     * @param sheetName
     * @return
     * @throws Exception 
     */
    public static String getProjectTypeCol(String sheetName) throws Exception
    {
        if (Func.checkNullOrEmpty(sheetName))
        {
            return null;
        }
        if (sheetMap == null || sheetMap.size() <= 0)
        {
            getDeispersionMeasure();
        }
        for (DispersionMeasureUtil dis : sheetMap)
        {
            if (sheetName.equals(dis.get("sheetName")))
            {
                return dis.getProjectTypeCol();
            }
        }
        return null;
    }

}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值