<%-- called from DecisionTableDetail.jsp file --%>

<%-- sets all the Scenarios and mappings of the corresponding DecisionTable --%>
<%@page import="java.util.*" 
%><%@page import="com.fujitsu.ibpm.dtm.*"
%><%@page import="com.fujitsu.ibpm.dtm.engine.datamatch.NumericDataMatch"
%><%@page import="java.io.*"
%>
<%
    boolean debugTrace=false;
    DecisionTableManager dtmManager = (DecisionTableManager) session.getAttribute("DecisionTableManager");
    String decisionTableIdStr = request.getParameter("decisionTableId");
    String actionString = request.getParameter("pageaction");
    String scenarioIdStr = request.getParameter("scenarioId");
     String editUrl = "ScenarioDetail.jsp";

    boolean isActive = false;
    String isInActiveStr = request.getParameter("isActive");
    if(isInActiveStr!=null){
        isActive = new Boolean(isInActiveStr).booleanValue();}
        session.setAttribute("isActive",""+isActive);


        session.setAttribute("DecisionTableManager",dtmManager);
        Scenario scenario = null;
        int decisionTableId = (new Integer(decisionTableIdStr)).intValue();
        debugLocal(debugTrace, out, "\n decisionTableId="+decisionTableId);
        DecisionTable decisionTable = dtmManager.getDecisionTable(decisionTableId); // Returns the specified DecisionTable

        //Used for backup
        DecisionTable backUpDt = null;

        //returns to the home page if user logoff before saving the decision table in the DecisionTableManagement.jsp page
        if(decisionTable==null)
        {
            response.sendRedirect("DecisionTableManagement.jsp");
            return;
        }

        //get selection header
        List possibleSelections = decisionTable.getPossibleSelections();//Returns the Related Selections
        Iterator possibleSelectionsItr = possibleSelections.iterator();
        List conditionKeys = decisionTable.getConditionKeys(); // returns all the Condition Keys
        Iterator conditionKeysItr = conditionKeys.iterator();

        //used for when primary or secondary condition deleted but its corresponding composite condition exists
    boolean isCompositAffected = false;
    ArrayList conditionKeysBeforeRemove = new ArrayList();

  if (actionString != null && actionString.length() > 0) {
        if (actionString.equals("viewDecisionTable")) {
            isActive=true;
            session.setAttribute("isActive",""+isActive);

         }     else      if (actionString.equals("delete")) {
              int scenarioId = (new Integer(scenarioIdStr)).intValue();
             dtmManager.deleteScenario(decisionTableId,scenarioId);
         }     else if (actionString.equals("moveUp")) {
                 int scenarioId = (new Integer(scenarioIdStr)).intValue();
                   decisionTable = dtmManager.chengeScenarioSequence(decisionTableId,scenarioId,-1);

        }     else if (actionString.equals("moveDown")) {
                 int scenarioId = (new Integer(scenarioIdStr)).intValue();
                       decisionTable = dtmManager.chengeScenarioSequence(decisionTableId,scenarioId,1);
          }else if (actionString.equals("saveDecision")) {//saves scenario
              scenario = (Scenario) session.getAttribute("Scenario");

            //makes the primary and secondary condition back when the corresponding composite condition is deleted
            boolean isComposit=false;
              Iterator compositConditionSearchItr = conditionKeys.iterator();
              while(compositConditionSearchItr.hasNext()){
                   ConditionKey conditionKey = (ConditionKey) compositConditionSearchItr.next();
                        if(conditionKey.getType().equals(ConditionKey.COMPOSITE_VALUE)) {
                            if(conditionKey.getPrimaryKeyValues().size()>0)
                                isComposit=true;
                        }
            }

            boolean isconditionExist=false;
              Iterator compositSearchItr = conditionKeys.iterator();
              while(compositSearchItr.hasNext()){
                   ConditionKey conditionKey = (ConditionKey) compositSearchItr.next();
                 isconditionExist=decisionTable.isVisbleConditionKey(conditionKey);
                 if(isconditionExist  && !isComposit)conditionKey.setPassive(false);
              }


             //set conditions to scenario
              List conditions = new ArrayList();
              int index=1;

              boolean isPrimaryValues=false;

              while(conditionKeysItr.hasNext()){
                 ConditionKey conditionKey = (ConditionKey) conditionKeysItr.next();

                     if(!conditionKey.isPassive()){
                        int compositeKeyId = -1;
                            if(conditionKey.getType().equals(ConditionKey.COMPOSITE_VALUE)) {
                            compositeKeyId = conditionKey.getId();
                            }
                           if(compositeKeyId!=-1){   //handle composite condition
                             List primaryValues = conditionKey.getPrimaryKeyValues();
                             Iterator primaryValuesItr = primaryValues.iterator();
                             Map compositeValues = new HashMap();
                             int compositeIndex=1;
                             int primaryConditionKeyId = conditionKey.getPrimaryConditionKeyId();
                            String primaryKeyName = null;

                            if(primaryConditionKeyId!=-1){
                                ConditionKey primaryKey = decisionTable.getConditionKey(primaryConditionKeyId);
                                if(primaryKey!=null)
                                primaryKeyName=primaryKey.getName();
                //getting primary values
                             while(primaryValuesItr.hasNext()){
                             String key = primaryKeyName+"="+primaryValuesItr.next();

                            String value = request.getParameter("ConditionValue"+conditionKey.getId()+":"+compositeIndex);


                            //checks validation if user input is invalid
        if(value!=null && value.trim().length()!=0){
            if(primaryKey.getType().equals(primaryKey.NUMBER_VALUE)) {
                        String operator = NumericDataMatch.getNumericOperator(value);
                                if(operator==null){
                                    operator = NumericDataMatch.DEFAULT_OPERATOR;
                                    value=operator+value;
                                }

                if(value.length()>1){
                        String subConditionValue=value.substring(2,value.length());
                        String partConditionValue=value.substring(0,2);

                                if(!isInt(partConditionValue)){
                                     if (!isInt(value)&&(!isOper(value))) {
                                        session.setAttribute("isActive", "" + !isActive);
                                        throw new Exception("The value \""+value+"\" of the condition "+primaryKey.getName()+" does not match its type ("+primaryKey.getType()+").");
                                    }
                                }

                                else{
                                    if (!isInt(value)) {
                                        session.setAttribute("isActive", "" + !isActive);
                                        throw new Exception("The value \""+value+"\" of the condition "+primaryKey.getName()+" does not match its type ("+primaryKey.getType()+").");
                                    }
                                }
                                if(subConditionValue.length()>0){
                                    if(!isInt(subConditionValue)) {
                                        session.setAttribute("isActive", "" + !isActive);
                                        throw new Exception("The value \""+value+"\" of the condition "+primaryKey.getName()+" does not match its type ("+primaryKey.getType()+").");
                                    }
                                }
                }else{
                         if (!isInt(value)) {
                             session.setAttribute("isActive", "" + !isActive);
                            throw new Exception("The value \""+value+"\" of the condition "+primaryKey.getName()+" does not match its type ("+primaryKey.getType()+").");
                         }
                }
            }
        }
                            if(primaryKey.getType().equals(primaryKey.BOOLEAN_VALUE)) {
                                    if (!isBool(value)) {
                                        session.setAttribute("isActive", "" + !isActive);
                                        throw new Exception("The value \""+value+"\" of the condition "+primaryKey.getName()+" does not match its type ("+primaryKey.getType()+").");
                                    }
                            }



                            compositeIndex++;

                            compositeValues.put(key,value);
                             }
                            }
                             Condition condition = new Condition(index++,"Condition"+index,conditionKey.getId());
                             condition.setCompositeValueList(compositeValues);

                             conditions.add(condition);
                          }else{
                            String conditionValue = request.getParameter("ConditionValue"+conditionKey.getId()).toString();



                            //checks validation if user input is invalid
        if(conditionValue!=null && conditionValue.trim().length()!=0){
            if(conditionKey.getType().equals(ConditionKey.NUMBER_VALUE)) {
                        String operator = NumericDataMatch.getNumericOperator(conditionValue);
                                if(operator==null){
                                    operator = NumericDataMatch.DEFAULT_OPERATOR;
                                    conditionValue=operator+conditionValue;
                                }

                if(conditionValue.length()>1){
                        String subConditionValue=conditionValue.substring(2,conditionValue.length());
                        String partConditionValue=conditionValue.substring(0,2);

                                if(!isInt(partConditionValue)){
                                     if (!isInt(conditionValue)&&(!isOper(conditionValue))) {
                                         session.setAttribute("isActive", "" + !isActive);
                                         throw new Exception("The value \""+conditionValue+"\" of the condition "+conditionKey.getName()+" does not match its type ("+conditionKey.getType()+").");
                                     }
                                }
                                else{
                                    if (!isInt(conditionValue)) {
                                        session.setAttribute("isActive", "" + !isActive);
                                        throw new Exception("The value \""+conditionValue+"\" of the condition "+conditionKey.getName()+" does not match its type ("+conditionKey.getType()+").");
                                    }
                                }
                                if(subConditionValue.length()>0){
                                    if(!isInt(subConditionValue)) {
                                        session.setAttribute("isActive", "" + !isActive);
                                        throw new Exception("The value \""+conditionValue+"\" of the condition "+conditionKey.getName()+" does not match its type ("+conditionKey.getType()+").");
                                    }
                                }
                }else{
                         if (!isInt(conditionValue)) {
                             session.setAttribute("isActive", "" + !isActive);
                             throw new Exception("The value \""+conditionValue+"\" of the condition "+conditionKey.getName()+" does not match its type ("+conditionKey.getType()+").");
                         }
                }
            }
        }
                            if(conditionKey.getType().equals(ConditionKey.BOOLEAN_VALUE)) {
                                   if (!isBool(conditionValue)) {
                                       session.setAttribute("isActive", "" + !isActive);
                                       throw new Exception("The value \""+conditionValue+"\" of the condition "+conditionKey.getName()+" does not match its type ("+conditionKey.getType()+").");
                                   }
                            }


                            conditions.add(new Condition(index++,"Condition"+index,conditionKey.getId(),conditionValue));
                            }
                            }

              }

        // sets conditions to scenarios
              scenario.setConditions(dtmManager.formatConditions(decisionTable,conditions));

        //set selections
                 List selections = new ArrayList();
                 index=1;
                 while(possibleSelectionsItr.hasNext()){
                      String selection = possibleSelectionsItr.next().toString();

                      String selectionStr = request.getParameter("approval"+index);
                      if(selectionStr==null) selectionStr="";
                      selections.add(new Selection(index++,selection,selectionStr));
                }

                scenario.setSelections(selections);
                  dtmManager.saveScenario(decisionTableId,scenario);
                possibleSelectionsItr = possibleSelections.iterator();
                conditionKeysItr = conditionKeys.iterator();

        }if (actionString.equals("saveDecisionTable")) {// saves decisionTable
        //backup existig conditions

        //set condition keys
                List newConditionTypes = new ArrayList();
                List newConditionNames= new ArrayList();
                conditionKeys = new ArrayList();
                StringTokenizer ckSt = new StringTokenizer(request.getParameter("conditionKeys"),",");
                 int index=1;

        //separating condition name, type and manipulator from conditionKey
                while (ckSt.hasMoreTokens()) {
                     String ckPair = ckSt.nextToken();
                    String name = ckPair.substring(0,ckPair.indexOf("(")-1);
                    String manipulator = null;
                    String type="";
                    if(ckPair.indexOf("[")!=-1){
                            manipulator = ckPair.substring(ckPair.indexOf("[")+1,ckPair.indexOf("]"));
                            type = ckPair.substring(ckPair.indexOf("(")+1,ckPair.indexOf("["));
                            newConditionTypes.add(type);
                    }else{
                        type = ckPair.substring(ckPair.indexOf("(")+1,ckPair.indexOf(")"));
                        newConditionTypes.add(type);
                    }
                    ConditionKey ck = new ConditionKey(index++,name,type);

                    if(type.equals(ConditionKey.COMPOSITE_VALUE)) {
                        ck.setComposite(true);
                    }else {
                        newConditionNames.add(name);
                    }
                    if(manipulator!=null) ck.setConditionManipulator(manipulator);

                                conditionKeys.add(ck);
                 }

                List origConditionKeys = decisionTable.getConditionKeys();
                conditionKeysItr = origConditionKeys.iterator();


                List existConditionKeys = decisionTable.getConditionKeys();
    if(existConditionKeys!=null)
    {
                //check when the primary key or secondary key deleted without deleting the corresponding composit key
                    boolean isCompositExists = false;
                    int primaryConditionKeyId=-1;
                    int secondaryConditionKeyId=-1;
                    Iterator checkPrimAndSecdKeysItr = existConditionKeys.iterator();
        while(checkPrimAndSecdKeysItr.hasNext())
        {
            ConditionKey conditionKey = (ConditionKey) checkPrimAndSecdKeysItr.next();
            if(conditionKey.getType().equals(ConditionKey.COMPOSITE_VALUE))
             {
                        ConditionKey primaryCkey = null;
                        ConditionKey secondaryCKey = null;

                                primaryConditionKeyId=conditionKey.getPrimaryConditionKeyId();
                                    if(primaryConditionKeyId!=-1){
                                        primaryCkey = decisionTable.getConditionKey(primaryConditionKeyId);
                                    if(!newConditionNames.contains(primaryCkey.getName())){
                                            isCompositExists=true;
                                            break;
                                        }
                                        if(newConditionNames.contains(primaryCkey.getName())&&!newConditionTypes.contains(primaryCkey.getType())){
                                        isCompositExists=true;
                                            break;
                                        }
                                    }

                                    secondaryConditionKeyId=conditionKey.getSecondryConditionKeyId();
                                    if(secondaryConditionKeyId!=-1){
                                        secondaryCKey = decisionTable.getConditionKey(secondaryConditionKeyId);

                                    if(!newConditionNames.contains(secondaryCKey.getName())){
                                            isCompositExists=true;
                                            break;
                                        }
                                        if(newConditionNames.contains(secondaryCKey.getName())&&!newConditionTypes.contains(secondaryCKey.getType())){
                                        isCompositExists=true;
                                            break;
                                        }
                                    }
                }
            }
                            if(isCompositExists)
                                throw new Exception("The removed condition is already set as a composite condition. Please remove the corresponding composite condition first and then remove this condition.");


}//End check
                decisionTable.saveConditionKeys(conditionKeys);
                conditionKeys=decisionTable.getConditionKeys();
                conditionKeysItr = conditionKeys.iterator();


        //set selections
                List selections = new ArrayList();
                StringTokenizer st = new StringTokenizer(request.getParameter("roles"),",");
                 while (st.hasMoreTokens()) {
                     selections.add(st.nextToken());
                 }

                decisionTable.setPossibleSelections(selections);
                possibleSelections = decisionTable.getPossibleSelections();
                possibleSelectionsItr = possibleSelections.iterator();

        //set ProcessDefinitions
                List processDefinitions = new ArrayList();
                 st = new StringTokenizer(request.getParameter("processDefinitions"),",");
                 while (st.hasMoreTokens()) {
                     processDefinitions.add(st.nextToken());
                 }
                decisionTable.setProcessDefinitions(processDefinitions);

                if(decisionTable.getConditionKeys().size()<1 && decisionTable.getPossibleSelections().size()<1){

                List scenarios = decisionTable.getScenarios();
                scenarios.clear();
                decisionTable.setScenarios(scenarios);
                }
            }else if (actionString.equals("saveMapping")) {//saves condition mapping
                Mapping mapping = (Mapping) session.getAttribute("Mapping");
        //set valueMappings for condition keys
                Map valueMappings = new HashMap();
                StringTokenizer ckSt = new StringTokenizer(request.getParameter("values"),",");
                 int index=1;
        //separates input and substitute valueMappings
                while (ckSt.hasMoreTokens()) {
                     String ckPair = ckSt.nextToken();
                    String name = ckPair.substring(0,ckPair.indexOf("(")-1);
                     String substitute = ckPair.substring(ckPair.indexOf("(")+1,ckPair.indexOf(")"));
                    valueMappings.put(name,substitute);
                 }

                mapping.setValueMappings(valueMappings);
                conditionKeys = decisionTable.getConditionKeys();
                conditionKeysItr = conditionKeys.iterator();
        //set data references
                List dataReferences = new ArrayList();
                StringTokenizer st = new StringTokenizer(request.getParameter("datas"),",");

                //separating dataReferences
                while (st.hasMoreTokens()) {
                     dataReferences.add(st.nextToken());
                 }
                String mappingDescription = request.getParameter("mappingDescription");
                if(mappingDescription!=null) mapping.setDescription(mappingDescription);
                mapping.setDataFieldReferences(dataReferences);
                dtmManager.saveMapping(decisionTableId,mapping);

        } else if (actionString.equals("saveResultMapping")) {//saves result mappings
                Mapping mapping = (Mapping) session.getAttribute("Mapping");

        //set data references
                List dataReferences = new ArrayList();
                StringTokenizer st = new StringTokenizer(request.getParameter("datas"),",");
                 while (st.hasMoreTokens()) {//separating dataReferences
                     dataReferences.add(st.nextToken());
                 }
                String mappingDescription = request.getParameter("mappingDescription");
                if(mappingDescription!=null) mapping.setResultDescription(mappingDescription);
                mapping.setResultDescription(mappingDescription);
                mapping.setResultDataFieldReferences(dataReferences);
                dtmManager.saveResultMapping(decisionTableId,mapping);

        }

         else if (actionString.equals("saveCompositeKey")) {// saves composite keys
            String compositeKeyIdStr = request.getParameter("compositeKeyId");
            int compositeKeyId = (new Integer(compositeKeyIdStr)).intValue();
            ConditionKey compositeKey = decisionTable.getConditionKey(compositeKeyId);

    //set Primary Key Values

            String primaryConditionValue = request.getParameter("primaryConditionValue");
            String secondaryConditionValue = request.getParameter("secondaryConditionValue");


            int primaryConditionKeyId=-1;
            int secondaryConditionKeyId=-1;
            boolean isCompositAlreadySet = false;
            boolean isPrimaryExist = false;
            boolean isSecondaryExist=false;
            Iterator checkCompositeKeysItr = conditionKeys.iterator();
                while(checkCompositeKeysItr.hasNext()){
                    ConditionKey conditionKey = (ConditionKey) checkCompositeKeysItr.next();
                    if(conditionKey.getType().equals(ConditionKey.COMPOSITE_VALUE)) {

                        if(conditionKey.getId()!=compositeKeyId){

                            primaryConditionKeyId=conditionKey.getPrimaryConditionKeyId();
                            ConditionKey primaryCkey = decisionTable.getConditionKey(primaryConditionKeyId);
                            if(primaryCkey!=null){
                            if(primaryCkey.getName().equals(primaryConditionValue))
                                    isPrimaryExist=true;
                            }
                            secondaryConditionKeyId=conditionKey.getSecondryConditionKeyId();
                            ConditionKey secondaryCKey = decisionTable.getConditionKey(secondaryConditionKeyId);
                            if(secondaryCKey!=null){
                            if(secondaryCKey.getName().equals(secondaryConditionValue))
                                    isSecondaryExist=true;
                            }
                        }
                    }
                }
                    if(isPrimaryExist==true && isSecondaryExist==true) isCompositAlreadySet=true;
                if(isCompositAlreadySet==true)
                    throw new Exception (primaryConditionValue+" and "+secondaryConditionValue+" has already set as composite keys.");


            if(isCompositAlreadySet==false){
                List primaryKeyValues = new ArrayList();
                String[] st =request.getParameter("primaryKeyValues").split("&sep;");

                for(int index=0;index<st.length;index++) {
                    primaryKeyValues.add(st[index]);
                }

                compositeKey.setPrimaryKeyValues(primaryKeyValues);

                ConditionKey primaryKey = decisionTable.getConditionKey(primaryConditionValue);
                ConditionKey secondaryKey = decisionTable.getConditionKey(secondaryConditionValue);
                compositeKey.setPrimaryConditionKeyId(primaryKey.getId());
                compositeKey.setSecondryConditionKeyId(secondaryKey.getId());
                primaryKey.setPassive(true);
                secondaryKey.setPassive(true);
                decisionTable.saveConditionKey(primaryKey);
                decisionTable.saveConditionKey(secondaryKey);
                decisionTable.saveConditionKey(compositeKey);
            }
}

    session.setAttribute("toBeSaved","true");

  }
session.setAttribute("isActive", "" + !isActive);
String decisionTableNote="";
if(decisionTable.getType().equals(decisionTable.PRIMARY_CONSTRAINT)) decisionTableNote="Note: In Primary DecisionTable Last scenario is default scenario and will be selected in case no scenario is matched with input data";
%>

<%!

public
    boolean
    isInt(
        String text)
    {
        boolean isMatch = false;
        if (text != null && text.length()>0)
        {
            try
            {
                if (text.startsWith(" ") || text.endsWith(" ")) {
                    isMatch = false;
                } else {
                    Double i = Double.valueOf(text);
                    isMatch = true;
                }
            }
            catch(NumberFormatException e)
            {
                isMatch = false;
            }
        }
        return isMatch;
    }

    public
    boolean
    isBool(
        String text)
    {
        boolean isMatch = false;
        if (text != null && text.length()>0)
        {
             if (text.equalsIgnoreCase("true") ||
                text.equalsIgnoreCase("false"))
            {
                isMatch = true;
            }
        }
        return isMatch;
    }
    
    public
         boolean
        isOper(String conditionValue)
        {
        String subConditionValue=conditionValue.substring(0,2);
    
            switch(subConditionValue.charAt(0))
            {
                case '<':if(subConditionValue.length()>0)
                            {
                                String temp=String.valueOf(subConditionValue.charAt(1));
                                if(subConditionValue.charAt(1)=='=')return true;
                                else if(isInt(temp))return true;
                                else return false;
                            }
                            return true;
                case '>':if(subConditionValue.length()>0)
                            {
                                String temp=String.valueOf(subConditionValue.charAt(1));
                                if(subConditionValue.charAt(1)=='=')return true;
                                else if(isInt(temp))return true;
                                else return false;
                            }
                            return true;
                case '=':if(subConditionValue.length()>0)
                            {
                                String temp=String.valueOf(subConditionValue.charAt(1));
                                if(isInt(temp))return true;
                                else return false;
                            }
                            return true;
                case '!':if(subConditionValue.length()>0)
                            {
                                String temp=String.valueOf(subConditionValue.charAt(1));
                                if(subConditionValue.charAt(1)=='=')return true;
                                else if(isInt(temp))return true;
                                else return false;
                            }
                            return true;
                default:if(isInt(subConditionValue))return true;
                        else    return false;
            }
    }
	
    public void debugLocal (boolean trace, Writer out, String msg) throws Exception
        {
            if (trace) {
                System.out.println(msg);
            }
    }

%>
