/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xmlpackage;

import CommonFunctions.CommonFunctions;
import java.io.File;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import structures.ActionTag;
import structures.ConditionTag;
import structures.Constants;
import structures.RuleSet;
import structures.Rule;

/*class RuleReader
 * Parses the rule xml file 
 */
public class RuleReader {

    public RuleSet ruleXML = new RuleSet();

    public void ExtractFromFile(File xmlFile) {
        try {
            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(xmlFile);
            ExtractRules(doc);

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void ExtractRules(Document doc) {
        try {
            NodeList listRuleSet = doc.getElementsByTagName(Constants.RULE_SET);
            Node sections = listRuleSet.item(0);
            if (sections.getNodeType() == Node.ELEMENT_NODE) {
                Element singleSection = (Element) sections;
                NodeList listRules = singleSection.getElementsByTagName(Constants.RULES);
                for (int i = 0; i < listRules.getLength(); i++) {
                    Rule rule = new Rule();
                    Node subSections = listRules.item(i);
                    if (subSections.getNodeType() == Node.ELEMENT_NODE) {
                        Element singleSubSection = (Element) subSections;
                        NodeList IDList = singleSubSection.getElementsByTagName(Constants.RULE_ID);
                        rule = ExtractRuleID(IDList, rule);
                        NodeList conditionList = singleSubSection.getElementsByTagName(Constants.RULE_CONDITIONS);
                        for (int j = 0; j < conditionList.getLength(); j++) {
                            Node conditionSection = conditionList.item(j);
                            if (conditionSection.getNodeType() == Node.ELEMENT_NODE) {
                                Element singleCondition = (Element) conditionSection;
                                NodeList listSingleConditions = singleCondition.getElementsByTagName(Constants.CONDITION);
                                rule = ExtractConditions(listSingleConditions, rule);

                            }
                        }
                        NodeList actionList = singleSubSection.getElementsByTagName(Constants.RULE_ACTIONS);
                        for (int j = 0; j < actionList.getLength(); j++) {
                            Node actionSection = actionList.item(j);
                            if (actionSection.getNodeType() == Node.ELEMENT_NODE) {
                                Element singleAction = (Element) actionSection;
                                NodeList listSingleAction = singleAction.getElementsByTagName(Constants.ACTION);
                                rule = ExtractActions(listSingleAction, rule);

                            }
                        }
                        ruleXML.getRuleSetVector().add(rule);
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public Rule ExtractActions(NodeList typeList, Rule tmp) {
        for (int i = 0; i < typeList.getLength(); i++) {
            ActionTag tmpCondition = new ActionTag();
            Node subSections = (Node) typeList.item(i);
            if (subSections.getNodeType() == Node.ELEMENT_NODE) {
                Element singleSubSection = (Element) subSections;
                NodeList functionList = singleSubSection.getElementsByTagName(Constants.ACTION_FUNCTION);
                tmpCondition = ExtractActionFunction(functionList, tmpCondition);
                tmp.getActionVector().add(tmpCondition);
            }

        }

        return tmp;
    }

    public Rule ExtractRuleID(NodeList typeList, Rule tmp) {
        if (typeList.getLength() > 0) {
            Element termname = (Element) typeList.item(0);
            NodeList type = termname.getChildNodes();
            tmp.setID(((Node) type.item(0)).getNodeValue());
        }
        return tmp;
    }

    public ActionTag ExtractActionFunction(NodeList typeList, ActionTag tmp) {
        if (typeList.getLength() > 0) {
            Element termname = (Element) typeList.item(0);
            NodeList type = termname.getChildNodes();
            tmp.setFunctionName(((Node) type.item(0)).getNodeValue());
        }
        return tmp;
    }

    public Rule ExtractConditions(NodeList typeList, Rule tmp) {
        for (int i = 0; i < typeList.getLength(); i++) {
            ConditionTag tmpCondition = new ConditionTag();
            Node subSections = (Node) typeList.item(i);
            if (subSections.getNodeType() == Node.ELEMENT_NODE) {
                Element singleSubSection = (Element) subSections;
                NodeList negationList = singleSubSection.getElementsByTagName(Constants.CONDITION_NOT);
                tmpCondition = ExtractConditionNot(negationList, tmpCondition);
                NodeList functionList = singleSubSection.getElementsByTagName(Constants.CONDITION_FUNCTION);
                tmpCondition = ExtractConditionFunction(functionList, tmpCondition);
                NodeList operatorList = singleSubSection.getElementsByTagName(Constants.CONDITION_LOGIGAL_OPERATOR);
                tmpCondition = ExtractConditionOperator(operatorList, tmpCondition);
                tmp.getConditionVector().add(tmpCondition);
            }

        }

        return tmp;
    }

    public ConditionTag ExtractConditionNot(NodeList typeList, ConditionTag tmp) {
        if (typeList.getLength() > 0) {
            Element termname = (Element) typeList.item(0);
            NodeList type = termname.getChildNodes();
            if (type.item(0)== null) {
                tmp.setNegation("");
            } else {
                tmp.setNegation(((Node) type.item(0)).getNodeValue());
            }
        }
        return tmp;
    }

    public ConditionTag ExtractConditionOperator(NodeList typeList, ConditionTag tmp) {
        if (typeList.getLength() > 0) {
            Element termname = (Element) typeList.item(0);
            NodeList type = termname.getChildNodes();
            if (type.item(0)== null) {
                tmp.setLogicalOperator("");
            } else {
                tmp.setLogicalOperator(((Node) type.item(0)).getNodeValue());
            }
        }
        return tmp;
    }

    public ConditionTag ExtractConditionFunction(NodeList typeList, ConditionTag tmp) {
        if (typeList.getLength() > 0) {
            Element termname = (Element) typeList.item(0);
            NodeList type = termname.getChildNodes();
            tmp.setFunctionName(((Node) type.item(0)).getNodeValue());
        }
        return tmp;
    }

}
