예제 #1
0
        private void ReadInfo(ExeXml.Fun fun, string funId, out Dictionary <string, Tuple <string, string> > changes,
                              out ExeXml.Par parRunCond, out List <ExeXml.Par> parDatabaseName)
        {
            parRunCond = null; parDatabaseName = new List <ExeXml.Par>();
            changes    = new Dictionary <string, Tuple <string, string> >(); // key: group, value.item1: fun/pol-ident, value.item2: on/off
            foreach (var par in fun.pars.Values)
            {
                if (par.Name.ToLower() == DefPar.Common.Run_Cond.ToLower()) // Run_Cond = { xxx }
                {
                    parRunCond = par;
                }
                else if (par.Name.ToLower() == DefQuery.Par.DataBasename.ToLower())  // #_DatabaseName is the only footnote-parameter possible
                {
                    parDatabaseName.Add(par);                                        // for global conditions (i.e. the Run_Cond)
                }
                else if (par.Name.ToLower() == DefPar.ChangeSwitch.PolFun.ToLower()) // PolFun = Guid / PolFun = policy-name
                {
                    AddToChangeList(changes, par.Group, par.val, false, funId);
                }
                else if (par.Name.ToLower() == DefPar.ChangeSwitch.Switch_NewVal.ToLower()) // SwitchNewVal = on/off
                {
                    AddToChangeList(changes, par.Group, par.val, true, funId);
                }
                else
                {
                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                    {
                        isWarning = false,
                        message   = $"Change switch ({funId}): unknown parameter {par.Name}"
                    });
                }
            }

            if (parRunCond == null)
            {
                return;
            }

            // make sure that footnote-parameters (i.e. #_DatabasName) do not get into conflict with existing footnote-parameters (i.e. same group)
            List <int> replaceGroups = new List <int>();

            foreach (ExeXml.Par parDB in parDatabaseName)
            {
                if (!int.TryParse(parDB.Group, out int g))
                {
                    continue;                                        // ignore this rather unlikely case (just keep the strange group)
                }
                parDB.Group = GetNewGroup(g).ToString(); replaceGroups.Add(g);
            }
            replaceGroups.Sort(); replaceGroups.Reverse(); // avoid replacing ...#1...#12... with ...#9901...#99012...
            foreach (int group in replaceGroups)           // and hope there is no #9
            {
                parRunCond.val = parRunCond.val.Replace($"#{group}", $"#{GetNewGroup(group)}");
            }

            int GetNewGroup(int group)
            {
                return(group + 9900);
            }
        }
 private ExeXml.Fun CloneFun(ExeXml.Fun fun)
 {
     ExeXml.Fun clone = new ExeXml.Fun {
         Name = fun.Name, on = fun.on, order = fun.order
     };
     foreach (ExeXml.Par par in fun.pars.Values)
     {
         ExeXml.Par clonePar = new ExeXml.Par()
         {
             Name = par.Name, Group = par.Group, order = par.order, val = par.val
         };
         clone.pars.Add(Guid.NewGuid().ToString(), clonePar);
     }
     return(clone);
 }
 internal Description(Description parDesc, string _queryName)
 {
     pol = parDesc.pol; fun = parDesc.fun; funID = parDesc.funID; par = parDesc.par; parID = parDesc.parID; queryName = _queryName;
 }
 internal Description(Description funDesc, ExeXml.Par _par, string _parID = null)
 {
     pol = funDesc.pol; fun = funDesc.fun; funID = funDesc.funID; par = _par; parID = _parID;
 }
예제 #5
0
        private void ApplyInfo(Dictionary <ExeXml.Fun, bool> switchInfo, ExeXml.Par switchFunRunCond, List <ExeXml.Par> switchFunDatabaseName)
        {
            foreach (var si in switchInfo)
            {
                ExeXml.Fun fun = si.Key; bool on = si.Value;

                // read-time change - simply change the switch as required
                if (switchFunRunCond == null)
                {
                    fun.on = on; continue;
                }

                // run-time change: implement switch by editing or adding the function's RunCond
                var hasRunCond = from p in fun.pars.Values
                                 where p.Name.ToLower() == DefPar.Common.Run_Cond.ToLower()
                                 select p;
                // function does not yet have a RunCond: add a copy of the ChangeSwitch-RunCond
                if (hasRunCond == null || hasRunCond.Count() == 0)
                {
                    if (fun.Name.ToLower() != DefFun.DefTu.ToLower() && // DefTU and DefIL do not accept a RunCond (does not make sense)
                        fun.Name.ToLower() != DefFun.DefIl.ToLower())   // and it does no harm if these definitions exist
                    {
                        ExeXml.Par newRunCond = new ExeXml.Par()
                        {
                            Name = DefPar.Common.Run_Cond
                        };
                        // function is currently on, switch off if RunCon is fulfilled
                        // i.e. run as long as ChangeSwitch-RunCond is not fulfilled
                        if (fun.on)
                        {
                            newRunCond.val = $"!({switchFunRunCond.val})";
                        }
                        // function is currently off, switch on if RunCond is fulfilled
                        // needs to be switched on, otherwise it is dropped by DropOff
                        // but do not run until ChangeSwitch-RunCond is fulfilled
                        else
                        {
                            fun.on = true; newRunCond.val = switchFunRunCond.val;
                        }
                        fun.pars.Add(Guid.NewGuid().ToString(), newRunCond);
                    }
                }
                // function has a RunCond: merge with the ChangeSwitch-RunCond
                else
                {
                    ExeXml.Par runCond = hasRunCond.First();
                    // function is currently on, switch off if RunCon is fulfilled
                    // run if current RunCond is fulfilled and as long as ChangeSwitch-RunCond is not fulfilled
                    if (fun.on)
                    {
                        runCond.val = $"!({switchFunRunCond.val}) & ({runCond.val})";
                    }
                    // function is currently off, switch on if RunCond is fulfilled
                    // needs to be switched on, otherwise it is dropped by DropOff
                    // but do not run until ChangeSwitch-RunCond is fulfilled, but still also fulfill current RunCond
                    else
                    {
                        fun.on = true; runCond.val = $"({switchFunRunCond.val}) & ({runCond.val})";
                    }
                }
                // transfer a possible #_DatabaseName-footnote from the switch-function to the function it is applied on
                foreach (ExeXml.Par dbName in switchFunDatabaseName)
                {
                    fun.pars.Add(Guid.NewGuid().ToString(), dbName);
                }
            }
        }
예제 #6
0
        private bool HandleBreak()
        {
            // CHECK IF THERE IS ANY BREAK FUNCTION ...
            string breakFunId = null; ExeXml.Fun breakFun = null; double breakFunOrder = double.MaxValue; Description funDesc = null;

            foreach (var pol in infoStore.country.cao.pols)
            {
                if (!pol.Value.on)
                {
                    continue;
                }
                foreach (var fun in pol.Value.funs)
                {
                    if (fun.Value.on && fun.Value.Name.ToLower() == DefFun.Break.ToLower())
                    {
                        double o = GetOrder(pol.Value.order, fun.Value.order);
                        if (o < breakFunOrder) // only consider 1stBreak in spine (if there are foolishly more)
                        {
                            breakFunId    = fun.Key; breakFun = fun.Value;
                            breakFunOrder = o; funDesc = new Description(pol.Value, breakFun, breakFunId);
                        }
                    }
                }
            }
            if (breakFun == null)
            {
                return(true);
            }

            // ... IF SO, CHECK PARAMETERS
            bool produceOutput = true, produceTUinfo = false; string outputFileName = string.Empty;

            foreach (var p in breakFun.pars)
            {
                string parID = p.Key; ExeXml.Par par = p.Value;
                if (par.val.ToLower() == DefPar.Value.NA)
                {
                    continue;
                }
                Description parDesc = new Description(funDesc, par, parID);

                if (par.Name.ToLower() == DefPar.Break.ProduceOutput.ToLower() || par.Name.ToLower() == DefPar.Break.ProduceTUinfo.ToLower())
                {
                    bool produceX = false;
                    if (par.val.ToLower() == DefPar.Value.YES)
                    {
                        produceX = true;
                    }
                    else if (par.val.ToLower() == DefPar.Value.NO)
                    {
                        produceX = false;
                    }
                    else
                    {
                        IssueErr(parDesc, "invalid value (must be yes or no)");
                    }
                    if (par.Name.ToLower() == DefPar.Break.ProduceOutput.ToLower())
                    {
                        produceOutput = produceX;
                    }
                    else
                    {
                        produceTUinfo = produceX;
                    }
                }
                else if (par.Name.ToLower() == DefPar.Break.OutputFileName.ToLower())
                {
                    outputFileName = par.val;
                }
                else
                {
                    IssueErr(parDesc, "unknown parameter");
                }
            }

            if (produceOutput == false && produceTUinfo == true)
            {
                IssueErr(funDesc, "TUinfo can only be produced if output is produced (parameter is ignored)", true);
            }

            if (infoStore.communicator.errorCount > 0)
            {
                return(false);
            }

            // IMPLEMENT THE BREAK
            // - main task: switch off everything after the Break function
            // - and, if necessary, search for DefOutput that can provide the output-filename (if not set by parameter OutputFileName)
            // - and, if necessary, find all TU names
            double        outputFunOrder = produceOutput && outputFileName == string.Empty ? double.MaxValue : -1; // the default for OutputFileName should be the first "normal" outputfile
            List <string> tuNames = new List <string>(); string indTUName = string.Empty;

            foreach (var pol in infoStore.country.cao.pols.Values)
            {
                if (!pol.on)
                {
                    continue;
                }
                foreach (var fun in pol.funs.Values)
                {
                    if (!fun.on)
                    {
                        continue;
                    }
                    double funOrder = GetOrder(pol.order, fun.order);
                    if (funOrder > breakFunOrder)
                    {
                        fun.on = false;                           // switch off everything after the Break function
                    }
                    if (fun.Name.ToLower() == DefFun.DefOutput.ToLower() &&
                        funOrder < outputFunOrder && funOrder > breakFunOrder) // get the File paramter of the first DefOutput after the Break
                    {
                        var fn = from p in fun.pars.Values where p.Name.ToLower() == DefPar.DefOutput.File.ToLower() select p.val;
                        if (fn.Count() > 0)
                        {
                            outputFileName = fn.First(); outputFunOrder = funOrder;
                        }
                    }

                    // if necessary, find at least one individual TU for output function, or all (active) TUs if TUinfo should be produced
                    if (!fun.on || !produceOutput || fun.Name.ToLower() != DefFun.DefTu.ToLower())
                    {
                        continue;
                    }

                    var tuNamePar = from p in fun.pars.Values where p.Name.ToLower() == DefPar.DefTu.Name.ToLower() select p.val;
                    var tuTypePar = from p in fun.pars.Values where p.Name.ToLower() == DefPar.DefTu.Type.ToLower() select p.val;
                    if (tuNamePar.Count() == 0 || tuTypePar.Count() == 0)
                    {
                        continue;
                    }
                    if (produceTUinfo)
                    {
                        tuNames.Add(tuNamePar.First());
                    }
                    if (indTUName == string.Empty && tuTypePar.First().ToUpper() == DefPar.Value.TUTYPE_IND)
                    {
                        indTUName = tuNamePar.First();
                    }
                }
            }

            // if necessary produce DefOutput function in redefining the Break function, which is not required anymore
            if (produceOutput == false)
            {
                breakFun.on = false; return(true);
            }
            if (outputFileName == string.Empty)
            {
                IssueErr(funDesc, "no name for the output file found"); return(false);
            }
            if (indTUName == string.Empty)
            {
                IssueErr(funDesc, "no DefTU with Type=IND found (required as DefOutput's TAX_UNIT)"); return(false);
            }

            int iGroup = 0, order = 0;

            breakFun.Name = DefFun.DefOutput; breakFun.pars.Clear();
            breakFun.pars.Add(Guid.NewGuid().ToString(), new ExeXml.Par()
            {
                Name = DefPar.DefOutput.File, val = outputFileName, order = (++order).ToString()
            });
            breakFun.pars.Add(Guid.NewGuid().ToString(), new ExeXml.Par()
            {
                Name = DefPar.DefOutput.VarGroup, val = "*", order = (++order).ToString()
            });
            breakFun.pars.Add(Guid.NewGuid().ToString(), new ExeXml.Par()
            {
                Name = DefPar.DefOutput.ILGroup, val = "*", order = (++order).ToString()
            });
            breakFun.pars.Add(Guid.NewGuid().ToString(), new ExeXml.Par()
            {
                Name = DefPar.Common.TAX_UNIT, val = indTUName, order = (++order).ToString()
            });

            foreach (string tuName in tuNames)
            {
                string sGroup = (++iGroup).ToString();
                breakFun.pars.Add(Guid.NewGuid().ToString(), new ExeXml.Par()
                {
                    Name = DefPar.DefOutput.UnitInfo_TU, val = tuName, Group = sGroup, order = (++order).ToString()
                });
                foreach (string uiId in new List <string> {
                    DefPar.Value.UNITINFO_HEADID, DefPar.Value.UNITINFO_ISPARTNER, DefPar.Value.UNITINFO_ISDEPCHILD,
                    DefPar.Value.UNITINFO_ISOWNCHILD, DefPar.Value.UNITINFO_ISOWNDEPCHILD, DefPar.Value.UNITINFO_ISDEPPARENT,
                    DefPar.Value.UNITINFO_ISDEPRELATIVE, DefPar.Value.UNITINFO_ISLONEPARENT
                })
                {
                    breakFun.pars.Add(Guid.NewGuid().ToString(), new ExeXml.Par()
                    {
                        Name = DefPar.DefOutput.UnitInfo_Id, val = uiId, Group = sGroup, order = (++order).ToString()
                    });
                }
            }

            void IssueErr(Description d, string m, bool isW = false)
            {
                infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                {
                    isWarning = isW, message = $"{d.Get()}: {m}"
                });
            }

            return(true);
        }