Package heart.parser.hml

Source Code of heart.parser.hml.HMLParser

/**
*
*     Copyright 2013-15 by Szymon Bobek, Grzegorz J. Nalepa, Mateusz Ślażyński
*
*
*     This file is part of HeaRTDroid.
*     HeaRTDroid is a rule engine that is based on HeaRT inference engine,
*     XTT2 representation and other concepts developed within the HeKatE project .
*
*     HeaRTDroid is free software: you can redistribute it and/or modify
*     it under the terms of the GNU General Public License as published by
*     the Free Software Foundation, either version 3 of the License, or
*     (at your option) any later version.
*
*     HeaRTDroid is distributed in the hope that it will be useful,
*     but WITHOUT ANY WARRANTY; without even the implied warranty of
*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*     GNU General Public License for more details.
*
*     You should have received a copy of the GNU General Public License
*     along with HeaRTDroid.  If not, see <http://www.gnu.org/licenses/>.
*
**/


package heart.parser.hml;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;

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

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import heart.State;
import heart.StateElement;
import heart.alsvfd.*;
import heart.exceptions.BuilderException;
import heart.exceptions.NotInTheDomainException;
import heart.exceptions.RangeFormatException;
import heart.xtt.*;


public class HMLParser {
  public static final String HML = "hml";
  public static final String VERSION  = "version";
  public static final String HML_TYPE = "type";
  public static final String HML_ATTRIBUTE = "attr";
  public static final String HML_STATE = "state";
  public static final String HML_TABLE = "table";
 
  public static final String ID = "id";
  public static final String NAME = "name";
  public static final String ATTREF = "attref";
  public static final String REF = "ref";
  public static final String SET= "set";
 
  public static final String TYPE_BASE = "base";
  public static final String TYPE_LENGTH = "length";
  public static final String TYPE_SCALE = "scale";
  public static final String TYPE_DOMAIN = "domain";
  public static final String TYPE_VALUE = "value";
  public static final String TYPE_ORDERED = "ordered";
  public static final String TYPE_DESC = "desc";
 
  public static final String VALUE_IS = "is";
  public static final String VALUE_FROM = "from";
  public static final String VALUE_TO = "to";
  public static final String VALUE_NUM = "num";
  public static final String VALUE_IN = "in";
  public static final String VALUE_NOTIN = "notin";
  public static final String VALUE_SIM = "sim";
  public static final String VALUE_NOTSIM = "sim";
  public static final String VALUE_SUPSET = "supset";
  public static final String VALUE_SUBSET = "subset";
 
  public static final String ATTR_TYPE = "type";
  public static final String ATTR_ABBREV = "abbrev";
  public static final String ATTR_CLASS = "class";
  public static final String ATTR_COMM = "comm"
  public static final String ATTR_CLB = "clb";

  public static final String TABLE_SCHM = "schm";
  public static final String TABLE_RULE = "rule";
  public static final String TABLE_PRECOND = "precondition";
  public static final String TABLE_CONCLUSION = "conclusion";
 
  public static final String RULE_COND = "condition";
  public static final String RULE_REL = "relation";
  public static final String RULE_REL_NAME = "name";
 
  public static final String RULE_DEC = "decision";
  public static final String RULE_TRANS = "trans";
 
  public static final String RULE_LINK = "link";
  public static final String RULE_TABREF = "tabref";
  public static final String RULE_RULEREF = "ruleref";
  public static final String RULE_EXPR = "expr";
  public static final String RULE_EVAL= "eval";
 
 
  public static XTTModel parseHML(InputStream is) throws BuilderException, NotInTheDomainException, RangeFormatException{
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder;
    XTTModel model = new XTTModel(XTTModel.SOURCE_HML);
    try {
      dBuilder = dbFactory.newDocumentBuilder();
      Document hml = dBuilder.parse(is);
     
      NodeList hmlNodes =  hml.getElementsByTagName(HML);
     
      for(int index = 0; index < hmlNodes.getLength(); index++){
        Node mainNode  = hmlNodes.item(index);
       
        //check if the node is element node. It should be HML Element.
        //If it is not, continue to the main node
        if (mainNode.getNodeType() == Node.ELEMENT_NODE) {
          Element eElement = (Element) mainNode;
          String version  = eElement.getAttribute(VERSION);
          model.setVersion(version);
         
          //read core elements of HML node
          LinkedList<Type> types = readTypes(eElement,model);
          model.setTypes(types);
         
          LinkedList<Attribute> attributes = readAttributes(eElement,model);
          model.setAttributes(attributes);
         
          LinkedList<Table>  tables = readTables(eElement,model);
          model.setTables(tables);
         
        }else{
          continue;
        }
      }
    } catch (ParserConfigurationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (SAXException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return model;
  }

  private static LinkedList<Table> readTables(Element hmlElement, XTTModel model) throws RangeFormatException {
    NodeList tablesNodes =  hmlElement.getElementsByTagName(HML_TABLE);
    LinkedList<Table> tables = new LinkedList<Table>();
    LinkedList<BlindRule> blindRules = new LinkedList<BlindRule>();
   
    for(int index = 0; index < tablesNodes.getLength(); index++){
      Node mainNode  = tablesNodes.item(index);
        Table table = new Table();
      //check if the node is element node. It should be table Element.
      //If it is not, continue to the main node
      if (mainNode.getNodeType() == Node.ELEMENT_NODE) {
        //Read basic information about the table, like id and name
        Element tableElement = (Element) mainNode;
        if(tableElement.hasAttribute(ID)){
          table.setId(tableElement.getAttribute(ID));
        }
        if(tableElement.hasAttribute(NAME)){
          table.setName(tableElement.getAttribute(NAME));
        }
       
        //Now, go deeper and check schema of the table
        NodeList tableChilds = tableElement.getChildNodes();
        for(int n = 0; n < tableChilds.getLength(); n++){   
          Node tableChildNode  = tableChilds.item(n);
   
          if (tableChildNode.getNodeType() == Node.ELEMENT_NODE) {
            Element  tableChildElement = (Element)tableChildNode; 
            if(tableChildElement.getNodeName().equals(TABLE_SCHM)){
              //Preconditions
              NodeList preconditionNodeList = tableChildElement.getElementsByTagName(TABLE_PRECOND);
              for(int p = 0; p < preconditionNodeList.getLength(); p++){
                Node precondNode  = preconditionNodeList.item(p);
                if (precondNode.getNodeType() == Node.ELEMENT_NODE) {
                  Element precondElement = (Element) precondNode;
                  LinkedList<Attribute> precondition = readAttrefs(precondElement, model);
                  table.setPrecondition(precondition);
                  break;
                }
              }
             
              //Conclusions
              NodeList conclusionNodeList = tableChildElement.getElementsByTagName(TABLE_CONCLUSION);
              for(int c = 0; c < preconditionNodeList.getLength(); c++){
                Node conclNode  = conclusionNodeList.item(c);
                if (conclNode.getNodeType() == Node.ELEMENT_NODE) {
                  Element conclElement = (Element) conclNode;
                  LinkedList<Attribute> conclusions = readAttrefs(conclElement, model);
                  table.setConclusion(conclusions);
                }
              }
            }else if(tableChildElement.getNodeName().equals(TABLE_RULE)){
              //Now, go further and read rules
              //Do not go deeper, as they are defined on the same level as schm
             
              //Create BlindRule and assign rule ID
              BlindRule br = new BlindRule();
             
              if(tableChildElement.hasAttribute(ID)){
                br.id = tableChildElement.getAttribute(ID);
              }
              //Read conditions
              LinkedList<Formulae> conditions = readConditions(tableChildElement,model);
              br.conditions = conditions;
              //ReadDecisions
              LinkedList<Decision> decisions = readDecisions(tableChildElement,model);
              br.decisions = decisions;
              //Read Links
              LinkedList<String> tabLinks = new LinkedList<String>();
              LinkedList<String> ruleLinks = new LinkedList<String>();
             
              NodeList tabLinksNodeList = tableChildElement.getElementsByTagName(RULE_TABREF);
              for(int tl = 0; tl < tabLinksNodeList.getLength(); tl++){   
                Node tabLinkNode  = tabLinksNodeList.item(tl);
                if (tabLinkNode.getNodeType() == Node.ELEMENT_NODE) {
                  Element tablinkElement = (Element) tabLinkNode;
                  if(tablinkElement.hasAttribute(REF)){
                    tabLinks.add(tablinkElement.getAttribute(REF));
                  }
                }
               
              }
             
              br.tabLinks = tabLinks;
             
              NodeList ruleLinksNodeList = tableChildElement.getElementsByTagName(RULE_RULEREF);
              for(int rl = 0; rl < ruleLinksNodeList.getLength(); rl++){   
                Node ruleLinkNode  = ruleLinksNodeList.item(rl);
                if (ruleLinkNode.getNodeType() == Node.ELEMENT_NODE) {
                  Element rulelinkElement = (Element) ruleLinkNode;
                  if(rulelinkElement.hasAttribute(REF)){
                    ruleLinks.add(rulelinkElement.getAttribute(REF));
                  }
                }
              }
             
              br.ruleLinks = ruleLinks;
              br.ownerTableId = table.getId();
              blindRules.add(br);
            }
          }
        }
        if(table != null) tables.add(table);
      }
    }
    return connectModel(blindRules, tables);
  }
 
  private static LinkedList<Decision> readDecisions(Element ruleElement, XTTModel model) throws RangeFormatException {
    LinkedList<Decision> decisions = new LinkedList<Decision>();
    NodeList transitionNodes =  ruleElement.getElementsByTagName(RULE_TRANS);
    for(int index = 0; index < transitionNodes.getLength(); index++){
      Node mainNode  = transitionNodes.item(index);
      //check if the node is element node. It should be transition Element.
      //If it is not, continue to the main node
      if (mainNode.getNodeType() == Node.ELEMENT_NODE) {
        Element transitionElement = (Element) mainNode;
        Attribute left = null;
        Decision d = new Decision();
        NodeList transitionChildNodes = transitionElement.getChildNodes();
        for(int n = 0; n < transitionChildNodes.getLength(); n++){
          Node transitionChildNode  = transitionChildNodes.item(n);
          if (transitionChildNode.getNodeType() == Node.ELEMENT_NODE) {
            Element transitionChildElement = (Element) transitionChildNode;
            //Now, get the left hand side of transition which has to be attref.
            //TODO However, this also can be a right hand side as we may allow att = att
            if(transitionChildElement.getNodeName().equals(ATTREF)){
              if(transitionChildElement.hasAttribute(REF)){
                String attrId = transitionChildElement.getAttribute(REF);
                //This is the case, when we read first attref which is left hand side.
                if(left == null){
                  left = model.getAttributeById(attrId);
                  d.setAttribute(left);
                }else{
                  //This is the case whe we assign other  
                  Attribute right = model.getAttributeById(attrId);
                  d.setDecision(new RuntimeExpression(right, Expression.OP_END, null));
                }
              }
            }else{
              //read complex expression
              Expression e = readComplexExpression(transitionElement, d.getAttribute(), model);
              d.addExpression(e);
            }
          }
        } 
        decisions.add(d);
      }
    }
    return decisions;
  }
 
  private static Expression readComplexExpression(Element transRootElement, Attribute lhs, XTTModel model) throws RangeFormatException{
    Expression complexExpression = null;
    NodeList transitionChildNodes = transRootElement.getChildNodes();
    for(int n = 0; n < transitionChildNodes.getLength(); n++){
      Node transitionChildNode  = transitionChildNodes.item(n);
      if (transitionChildNode.getNodeType() == Node.ELEMENT_NODE) {
        Element transitionChildElement = (Element) transitionChildNode;
        if(transitionChildElement.getNodeName().equals(ATTREF)){
          if(transitionChildElement.hasAttribute(REF)){
            String attrId = transitionChildElement.getAttribute(REF);
            Attribute right = model.getAttributeById(attrId);
            complexExpression = new RuntimeExpression(right, Expression.OP_END, null)
          }
        }else if(transitionChildElement.getNodeName().equals(SET)){
          //This is static expression, so read values
          ArrayList<Value> values = parseValues(transitionChildElement, lhs.getType().getBase());
          if(values.size() > 1 || lhs.getXTTClass().equals(Attribute.CLASS_GENERAL) ){
            complexExpression= new StaticExpression(new SetValue(values), Expression.OP_END, null);
              }else {
                complexExpression = new StaticExpression(values.get(0), Expression.OP_END, null);
              }
        }else if(transitionChildElement.getNodeName().equals(RULE_EXPR)){
          //TODO: Not yet supported
        }else if(transitionChildElement.getNodeName().equals(RULE_EVAL)){
          String operation = transitionChildElement.getAttribute(NAME);
          Expression innerExpr = readComplexExpression(transitionChildElement, lhs, model);
          if(complexExpression != null){
            complexExpression.setOperator(operation);
            complexExpression.setExpression(innerExpr);
          }else{
            complexExpression = innerExpr;
          }
        }
      }
    }
    return complexExpression;
   
  }

  private static LinkedList<Formulae> readConditions(Element ruleElement, XTTModel model) throws RangeFormatException {
    LinkedList<Formulae> conditions = new LinkedList<Formulae>();
 
    NodeList relationNodes =  ruleElement.getElementsByTagName(RULE_REL);
    for(int index = 0; index < relationNodes.getLength(); index++){
      Node mainNode  = relationNodes.item(index);
      //check if the node is element node. It should be relation Element.
      //If it is not, continue to the main node
      if (mainNode.getNodeType() == Node.ELEMENT_NODE) {
        //check for relation name
          Formulae f = new Formulae();
        Element relationElement = (Element) mainNode;
        if(relationElement.hasAttribute(RULE_REL_NAME)){
          f.setOp(relationElement.getAttribute(RULE_REL_NAME));
       
          NodeList relationChilds = mainNode.getChildNodes();
          for(int n = 0; n < relationChilds.getLength(); n++){
            Node relationChildNode  = relationChilds.item(n);
            if (relationChildNode.getNodeType() == Node.ELEMENT_NODE) {
              //check which noe are we investigating
              Element relationChildElement = (Element) relationChildNode;
              if(relationChildElement.getNodeName().equals(ATTREF)){
                //read the name of the attribute we are comparing to
                if(relationChildElement.hasAttribute(REF)){
                  String attributeId = relationChildElement.getAttribute(REF);
                  Attribute att = model.getAttributeById(attributeId);
                  f.setAttribute(att);
                }
              }else if(relationChildElement.getNodeName().equals(SET)){
                //read values that we are comparing to
                //TODO: This in fact can be either value or attref, when we allow to compare
                //    attributes against other attributes.
                ArrayList<Value> values = parseValues(relationChildElement, f.getAttribute().getType().getBase());
                      //Depending on the number of read attributes either create general or simple value
                if(values.size() > 1 ||
                        f.getOp().equals(VALUE_IN) ||
                        f.getOp().equals(VALUE_NOTIN) ||
                        f.getAttribute().getXTTClass().equals(Attribute.CLASS_GENERAL)){
                      f.setValue(new SetValue(values))
                    }else{
                        f.setValue(values.get(0));
                    }
              }
            }
          }
         
          conditions.add(f);
        }
       
      }
    }
    return conditions;
  }
  /**
   * This method reads all attribute references that are on the level below the element given as an {@code eElement} parameter.
   * It does not read any of the attributes references that are nested within the {@code eElement} parameter.
   * @param eElement {@link Element} that should point exactly the level above the attribute references tags
   * @param model {@link XTT2Model} that is currently build
   * @return {@link LinkedList} of all {@link Attributes} that were referenced by the attref tags, and are present in {@code model} parameter.
   */
  private static LinkedList<Attribute> readAttrefs(Element eElement, XTTModel model) {
    NodeList attrefNodes =  eElement.getElementsByTagName(ATTREF);
    LinkedList<Attribute> attributes = new LinkedList<Attribute>();
    for(int index = 0; index < attrefNodes.getLength(); index++){
      Node mainNode  = attrefNodes.item(index);
       
      //check if the node is element node. It should be attref Element.
      //If it is not, continue to the main node
      if (mainNode.getNodeType() == Node.ELEMENT_NODE) {
        Element  attrefElement = (Element)mainNode;
        if(attrefElement.hasAttribute(REF) && attrefElement.getParentNode() == eElement){
          String attId = attrefElement.getAttribute(REF);
          Attribute a = model.getAttributeById(attId);
          attributes.add(a);
        }
      }
    }
    return attributes;
  }
 
 
  private static LinkedList<Table> connectModel(LinkedList<BlindRule> brules, LinkedList<Table> tables){
    ArrayList<Rule> rules = new ArrayList<Rule>(brules.size());
   
    //Fill the rules list with real rules, but without links
    for(BlindRule currentRule : brules){
      Rule rule = new Rule();
      rule.setId(currentRule.id);
      rule.setConditions(currentRule.conditions);
      rule.setDecisions(currentRule.decisions);
     
      rules.add(rule);
    }
   
    int currentRuleIndex = 0;
    for(BlindRule currentRule : brules){
      for(String toLinkRuleId : currentRule.ruleLinks){
        for(Rule other : rules){
          if(toLinkRuleId.equals(other.getId())){
            rules.get(currentRuleIndex).getRuleLinks().add(other);
            break;
          }
        }
      }
     
      for(String toLinkTableId : currentRule.tabLinks){
        for(Table table : tables){
          if(toLinkTableId.equals(table.getId())){
            rules.get(currentRuleIndex).getTabLinks().add(table);
            break;
          }
        }
      }
     
      for(Table table: tables){
        if(table.getId().equals(currentRule.ownerTableId)){
          table.getRules().add(rules.get(currentRuleIndex));
        }
      }
     
      currentRuleIndex++;
    }

    return tables;
  }
 

  private static LinkedList<State> readStates(Element hmlElement, XTTModel model) throws RangeFormatException {
    NodeList stateNodes =  hmlElement.getElementsByTagName(HML_STATE);
    LinkedList<State> states = new LinkedList<State>();
    for(int index = 0; index < stateNodes.getLength(); index++){
      Node mainNode  = stateNodes.item(index);
     
      State state = new State();
      Attribute attr = null;
      //check if the node is element node. It should be state Element.
      //If it is not, continue to the main node
      if (mainNode.getNodeType() == Node.ELEMENT_NODE) {
        Element stateElement = (Element) mainNode;
        if(stateElement.hasAttribute(ID)){
          state.setId(stateElement.getAttribute(ID));
         
        }
        if(stateElement.hasAttribute(NAME)){
          state.setName(stateElement.getAttribute(NAME));
        }
       
        //Get a list of state elements frm this element
        NodeList stateElements = stateElement.getChildNodes();
        StateElement stateElementObject = null;
        for(int se = 0; se < stateElements.getLength(); se++){
          Node finalStateNode  = stateElements.item(se);
          if (finalStateNode.getNodeType() == Node.ELEMENT_NODE) {
            Element finalStateElement = (Element) finalStateNode;
            if(finalStateElement.getNodeName().equals(ATTREF)){
              stateElementObject = new StateElement();
              String attrId = finalStateElement.getAttribute(REF);
              attr = model.getAttributeById(attrId);
              stateElementObject.setAttributeName(attr.getName());
            }else if(finalStateElement.getNodeName().equals(SET)){
              Type corresponginType = attr.getType();
              ArrayList<Value> values = parseValues(finalStateElement, corresponginType.getBase());
              if(values.size() > 1){
                stateElementObject.setValue(new SetValue(values));
              }else{
                stateElementObject.setValue(values.get(0));
              }
              state.addStateElement(stateElementObject);
            }
          }
        }
      }
      if(state != null) states.add(state);
    }
   
    return states;
   
  }

  private static LinkedList<Attribute> readAttributes(Element hmlElement, XTTModel model) throws BuilderException, NotInTheDomainException {
    NodeList attrNodes =  hmlElement.getElementsByTagName(HML_ATTRIBUTE);
    LinkedList<Attribute> attributes = new LinkedList<Attribute>();
    for(int index = 0; index < attrNodes.getLength(); index++){
      Node mainNode  = attrNodes.item(index);
     
      //check if the node is element node. It should be attribute Element.
      //If it is not, continue to the main node
      if (mainNode.getNodeType() == Node.ELEMENT_NODE) {
        Element attrElement = (Element) mainNode;
       
        String id = null;
        String name = null;
        String comm = null;
        String XTTClass = null;
        String description = null;
        String abbreviation = null;
        String callback = null;
        Type type = null;
       
        if(attrElement.hasAttribute(ID)){
          id = attrElement.getAttribute(ID);
        }
        if(attrElement.hasAttribute(ATTR_TYPE)){
          //Add type by searching in types that has already been added
          String typeId = attrElement.getAttribute(ATTR_TYPE);
          LinkedList<Type> types = model.getTypes();
          for(Type t : types){
            if(t.getId().equals(typeId)){
              type = t;
              break;
            }
          }
        }
        if(attrElement.hasAttribute(NAME)){
          name = attrElement.getAttribute(NAME);
        }
        if(attrElement.hasAttribute(ATTR_ABBREV)){
           abbreviation = attrElement.getAttribute(ATTR_ABBREV);
        }
        if(attrElement.hasAttribute(ATTR_CLASS)){
          XTTClass = attrElement.getAttribute(ATTR_CLASS);
        }
        if(attrElement.hasAttribute(ATTR_COMM)){
          comm = attrElement.getAttribute(ATTR_COMM);
        }
        if(attrElement.hasAttribute(ATTR_CLB)){
          callback = attrElement.getAttribute(ATTR_CLB);
        }
       
        Attribute attr = new Attribute.Builder().setId(id)
            .setName(name)
            .setType(type)
            .setCallback(callback)
            .setComm(comm)
            .setAbbreviation(abbreviation)
            .setDescription(description)
            .setXTTClass(XTTClass).build();
       
 
        attributes.add(attr);

      }
    }
    return attributes;
  }

  private static LinkedList<Type> readTypes(Element hmlElement, XTTModel model) throws BuilderException, RangeFormatException {
    NodeList typeNodes =  hmlElement.getElementsByTagName(HML_TYPE);
    LinkedList<Type> types = new LinkedList<Type>();
   
    for(int index = 0; index < typeNodes.getLength(); index++){
      Node mainNode  = typeNodes.item(index);
     
      //check if the node is element node. It should be type Element.
      //If it is not, continue to the main node
      if (mainNode.getNodeType() == Node.ELEMENT_NODE) {
        Element eElement = (Element) mainNode;
        String id  = eElement.getAttribute(ID);
        String name = eElement.getAttribute(NAME);
        String base = eElement.getAttribute(TYPE_BASE);
        String desc = null;
        String ordered = null;
        int length = 0;
        int precision = 0;
       
        ArrayList<Value> values = null;
       
        if(eElement.hasAttribute(TYPE_LENGTH)){
          length = Integer.parseInt(eElement.getAttribute(TYPE_LENGTH));
        }
        if(eElement.hasAttribute(TYPE_SCALE)){
          precision = Integer.parseInt(eElement.getAttribute(TYPE_SCALE));
        }
           
        //read description of a type
        NodeList description  =  eElement.getElementsByTagName(TYPE_DESC);

        for(int n = 0; n < description.getLength(); n++){
          Node descNode  = description.item(n);
          if (descNode.getNodeType() == Node.ELEMENT_NODE) {
            desc = descNode.getTextContent().trim();
          }
        }
       
        //read domain of a type
        NodeList domainList  =  eElement.getElementsByTagName(TYPE_DOMAIN);
       
        for(int n = 0; n < domainList.getLength(); n++){
          Node domainNode  = domainList.item(n);
          if (domainNode.getNodeType() == Node.ELEMENT_NODE) {
            Element domainElement = (Element) domainNode;
           
            //Check if the type is ordered
            if(domainElement.hasAttribute(TYPE_ORDERED)){
              ordered = domainElement.getAttribute(TYPE_ORDERED);
            }
           
            //Read domain values
            values = parseValues(domainElement, base);
          }
        }
       
        //All information are collecetd, so create a type and add it to the list
        Type newType = new Type.Builder().setId(id)
            .setName(name)
            .setBase(base)
            .setDescription(desc)
            .setLength(length)
            .setOrdered(ordered)
            .setPrecision(precision)
            .setDomain(new SetValue(values)).build();
       
        types.add(newType);
      }else{
        continue;
      }
    }
    return types;
  }
 
  private static ArrayList<Value> parseValues(Element parentElement, String typeBase) throws RangeFormatException{
    ArrayList<Value> values = new ArrayList<Value>();
    NodeList valueNodes =  parentElement.getElementsByTagName(TYPE_VALUE);
    //Iterate through all values and add them to the list
    for(int n = 0; n < valueNodes.getLength(); n++){
      Node valueNode  = valueNodes.item(n);
      if (valueNode.getNodeType() == Node.ELEMENT_NODE) {
        Element valueElement = (Element) valueNode;
        String is = null;
        String num = null;
        String from = null;
        String to = null;
        Value value = null;
       
       
        if(valueElement.hasAttribute(VALUE_IS)){
          is = valueElement.getAttribute(VALUE_IS);
            if(is.toLowerCase().equals(Value.ANY)){
              value = new Any();
              values.add(value);
              continue;
            }else if(is.toLowerCase().equals(Value.NULL)){
              value = new Null();
              values.add(value);
              continue;
            }else if(valueElement.hasAttribute(VALUE_NUM)){
            num = valueElement.getAttribute(VALUE_NUM);
          }
        }else if(valueElement.hasAttribute(VALUE_FROM)){
          from = valueElement.getAttribute(VALUE_FROM);
          to = valueElement.getAttribute(VALUE_TO);
        }
       
        //depending on the type base and class, create an exact value
        if(typeBase.equals(Type.BASE_NUMERIC)){
          // range numeric
                if(from != null && to != null){
                  SimpleNumeric snfrom = new SimpleNumeric(Double.parseDouble(from));
                  SimpleNumeric snto = new SimpleNumeric(Double.parseDouble(to));
                  Range rnvalue = new Range(snfrom,snto);
                 
                  value = rnvalue;
                }else{
                  SimpleNumeric snvalue = new SimpleNumeric();

                  snvalue.setValue(Double.parseDouble(is));

                  value = snvalue;
                }
              }else{
                //range symbolic (this apply only when the type is ordered)
                if(from != null && to != null){
                  SimpleSymbolic ssfrom = new SimpleSymbolic(from);
                  SimpleSymbolic ssto = new SimpleSymbolic(to);
                 
                  Range rsvalue = new Range(ssfrom,ssto);
                 
                 
                  value = rsvalue;
                }else{
                 
                  SimpleSymbolic ssvalue = new SimpleSymbolic(is);
                 
                  if(num != null) ssvalue.setOrder(Integer.valueOf(num));
                 
                  value = ssvalue;
                }
              }
       
        //Check if the value is not null and add it to the list
        if(value != null){
                values.add(value);
            }
      }
    }
    return values;
  }
}

/**
* This class represents a rule, but without references to other rules and tables.
* This connections re defined by the ruleLinks and tabLinks variables, and in the
* model they should be references to real objects.
* Because during parsing, there is no possibility to link rules and tables with objects that do not exists,
* first all links are read as String references, and later this BlindRule objects are transformed into real Rule objects.
* @author sbk
*
*/
class BlindRule {
  String id;
  String ownerTableId;
 
  LinkedList<String> ruleLinks;
  LinkedList<String> tabLinks;

  LinkedList<Formulae> conditions;
  LinkedList<Decision> decisions;
 
  public BlindRule() {
    ruleLinks = new LinkedList<String>();
    tabLinks =  new LinkedList<String>();
    conditions = new LinkedList<Formulae>();
    decisions = new LinkedList<Decision>();
  }
 
}
TOP

Related Classes of heart.parser.hml.HMLParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.