Exemplo n.º 1
0
        /// <summary> reads the relevant content of a add-on file into an ExeXml.AddOn structure (see ReadCountry for IMPORTANT NOTES) </summary>
        /// <param name="path"> full path to the add-on-xml-file </param>
        /// <param name="addOnSysIdentifier"> id or name of add-on-system, only info belonging to this system is read </param>
        public static ExeXml.AddOn ReadAddOn(string path, string addOnSysIdentifier, Communicator communicator)
        {
            try
            {
                ExeXml.AddOn addOn = new ExeXml.AddOn();

                // first read the xlm-file into simple property/value dictionaries ...
                Dictionary <string, Dictionary <string, string> > ctry, syss, pols, refPols, funs, pars, sysPols, sysFuns, sysPars;
                using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
                    using (XmlReader reader = XmlReader.Create(sr))
                    {
                        ctry    = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.COUNTRY, hasId: false, singleItem: true);
                        syss    = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.SYS);
                        pols    = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.POL);
                        refPols = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.REFPOL);
                        funs    = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.FUN);
                        pars    = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.PAR, hasId: false);
                        sysPols = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.SYS_POL, hasId: false);
                        sysFuns = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.SYS_FUN, hasId: false);
                        sysPars = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.SYS_PAR, hasId: false);
                    }

                // ... then analyse the info:
                GetCountryInfo(addOn.cao, ctry);

                string addOnSysId = GetIdByIdOrName(addOnSysIdentifier, syss, true); // search system by id or name (throws exeception if not found)

                GetPolInfo(addOnSysId, pols, sysPols, refPols, false, addOn.cao, out List <string> polErrors);
                foreach (string polError in polErrors)
                {
                    ReportError(communicator, path, polError);
                }

                GetFunInfo(addOnSysId, funs, sysFuns, refPols, false, addOn.cao, out List <string> funErrors);
                foreach (string funError in funErrors)
                {
                    ReportError(communicator, path, funError);
                }

                GetParInfo(addOnSysId, pars, sysPars, false, addOn.cao, out List <string> parErrors);
                foreach (string parError in parErrors)
                {
                    ReportError(communicator, path, parError);
                }

                // filter the add-on info out (for convenience, could actually also be done in the executable's add-on-handler)
                foreach (var pol in addOn.cao.pols)
                {
                    if (!pol.Value.name.ToLower().StartsWith(ExeXml.AddOn.POL_AO_CONTROL.ToLower()))
                    {
                        continue;
                    }

                    addOn.polAOControl = pol.Value;
                    foreach (var fun in pol.Value.funs)
                    {
                        if (fun.Value.Name.ToLower() != DefFun.AddOn_Applic.ToLower())
                        {
                            continue;
                        }
                        foreach (var par in fun.Value.pars)
                        {
                            if (par.Value.Name.ToLower() == ExeXml.AddOn.PAR_APPLIC_SYS && par.Value.val != DefPar.Value.NA)
                            {
                                addOn.applicSys.Add(par.Value.val);
                            }
                        }
                        pol.Value.funs.Remove(fun.Key);
                        break;
                    }

                    addOn.cao.pols.Remove(pol.Key);
                    break;
                }
                if (addOn.polAOControl == null)
                {
                    throw new Exception($"Policy {ExeXml.AddOn.POL_AO_CONTROL}* not found");
                }

                return(addOn);
            }
            catch (Exception exception)
            {
                throw new Exception($"Failure reading file {path}{Environment.NewLine}{exception.Message}");
            }
        }
        private static void GetParInfo(string sysId,
                                       Dictionary <string, Dictionary <string, string> > pars,
                                       Dictionary <string, Dictionary <string, string> > sysPars,
                                       bool ignorePrivate,
                                       ExeXml.CAO cao, out List <string> errors,
                                       bool readComment = false)
        {
            errors = new List <string>();

            foreach (Dictionary <string, string> sp in sysPars.Values)       // loop over <SYS_PARs>
            {
                if (sp.ContainsKey(TAGS.SYS_ID) && sp[TAGS.SYS_ID] == sysId) // consider only <SYS_PAR> with the appropriate <SYS_ID>
                {
                    ExeXml.Par par   = new ExeXml.Par();
                    string     parId = sp.GetOrEmpty(TAGS.PAR_ID);

                    if (parId == string.Empty)
                    {
                        continue;
                    }

                    if (!pars.ContainsKey(parId))
                    {
                        errors.Add($"No <{TAGS.PAR}> corresponds to <{TAGS.SYS_PAR}> with <{TAGS.PAR_ID}> {parId}"); continue;
                    }

                    if (ignorePrivate)
                    {
                        string priv = pars[parId].GetOrEmpty(TAGS.PRIVATE);
                        if (priv != null && priv == DefPar.Value.YES)
                        {
                            continue;                                           // ignore if private
                        }
                    }

                    //par.val = EM_Helpers.AdaptDecimalSign(XmlHelpers.RemoveCData(sp.GetOrEmpty(TAGS.VALUE)));
                    par.val = XmlHelpers.RemoveCData(sp.GetOrEmpty(TAGS.VALUE));
                    if (par.val == DefPar.Value.NA)
                    {
                        continue;                                 // ignore n/a
                    }
                    par.order = sp.GetOrEmpty(TAGS.ORDER);        // get <Order> for error messages (otherwise irrelevant for executable)

                    par.Name = pars[parId].GetOrEmpty(TAGS.NAME); // get Name, Group and FunId from <PARs>
                    if (readComment)
                    {
                        par.comment = XmlHelpers.RemoveCData(pars[parId].GetOrEmpty(TAGS.COMMENT));
                    }
                    string funId = pars[parId].GetOrEmpty(TAGS.FUN_ID);
                    par.Group = pars[parId].GetOrEmpty(TAGS.GROUP);

                    par.val = allowInnerWhitespace.Contains(par.Name.ToLower()) ? par.val.ToLower().Trim()
                                                                                : EM_Helpers.RemoveWhitespace(par.val.ToLower());

                    // assign the parameter to the corresponding function
                    foreach (var pol in cao.pols)                          // note that 'TryAdd' is actually necessary for parameters of
                    {
                        if (pol.Value.funs.ContainsKey(funId))             // reference policies, because the policies actually contain the
                        {
                            pol.Value.funs[funId].pars.TryAdd(parId, par); // same functions, not just copies of the same functions
                        }
                    }
                }
            }
        }
 public static Dictionary <string, bool> ReadVars(string path, Communicator communicator)
 {
     try
     {
         Dictionary <string, bool> content = new Dictionary <string, bool>(StringComparer.OrdinalIgnoreCase);
         using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
             using (XmlReader reader = XmlReader.Create(sr))
             {
                 foreach (var v in XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.VAR).Values)
                 {
                     if (!content.TryAdd(XmlHelpers.RemoveCData(v.GetOrEmpty(TAGS.NAME)),
                                         v.GetOrEmpty(TAGS.MONETARY) != "0"))
                     {
                         communicator.ReportError(new Communicator.ErrorInfo()
                         {
                             isWarning = true,
                             message   = $"{Path.GetFileName(path)}: double definition of variable {XmlHelpers.RemoveCData(v.GetOrEmpty(TAGS.NAME))} - second definition is ignored"
                         });
                     }
                 }
             }
         return(content);
     }
     catch (Exception exception)
     {
         throw new Exception($"Failure reading file {path}{Environment.NewLine}{exception.Message}");
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// reads the relevant content of a country file into an ExeXml.Country structure (see parameters and ExeXml.Country wrt 'relevant')
        /// IMPORTANT NOTES:
        /// - error-reporting:
        ///   - everything that does not at least allow analysing the info throws an exception (e.g. file not found, system not found, ...)
        ///   - other errors are reported via the communicator - if they still allow running the programme via isWarning=true
        ///   - "relaxed" error handling: unlikely errors (which are actually only possible by manual manipulation of the xml-file)
        ///      are ignored without comment, if they do not prohibit the run (if things still work - so what?)
        /// - polices and functions switched to n/a are not read
        /// </summary>
        /// <param name="path"> full path to the country-xml-file </param>
        /// <param name="sysIdentifier"> id or name of system, only info belonging to this system is read, e.g. only relevant uprating indices </param>
        /// <param name="dataIdentifier"> id or name, only info belonging to this dataset is read, e.g. only relevant uprating indices </param>
        /// <param name="ignorePrivate"> if true, private elements are ignored by the reader </param>
        /// <param name="readComment"> if false (default), comments are not read (as the executable does not need them) </param>
        public static ExeXml.Country ReadCountry(string path, string sysIdentifier, string dataIdentifier,
                                                 bool ignorePrivate, Communicator communicator, bool readComment = false)
        {
            try
            {
                ExeXml.Country country = new ExeXml.Country();

                // first read the xlm-file into simple property/value dictionaries ...
                Dictionary <string, Dictionary <string, string> > ctry, syss, pols, refPols, funs, pars, sysPols, sysFuns, sysPars,
                                                                  upInds, upIndYears, datas, sysDatas, extSwitch, localExt, extPol, extFun, extPar, indTaxes, indTaxYears;
                using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
                    using (XmlReader reader = XmlReader.Create(sr))
                    {
                        ctry        = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.COUNTRY, hasId: false, singleItem: true);
                        syss        = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.SYS);
                        pols        = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.POL);
                        refPols     = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.REFPOL);
                        funs        = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.FUN);
                        pars        = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.PAR, hasId: false);
                        sysPols     = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.SYS_POL, hasId: false);
                        sysFuns     = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.SYS_FUN, hasId: false);
                        sysPars     = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.SYS_PAR, hasId: false);
                        upInds      = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.UPIND);
                        upIndYears  = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.UPIND_YEAR, hasId: false);
                        datas       = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.DATA);
                        sysDatas    = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.SYS_DATA, hasId: false);
                        localExt    = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.LOCAL_EXTENSION);
                        extPol      = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.EXTENSION_POL, hasId: false);
                        extFun      = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.EXTENSION_FUN, hasId: false);
                        extPar      = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.EXTENSION_PAR, hasId: false);
                        extSwitch   = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.EXTENSION_SWITCH, hasId: false);
                        indTaxes    = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.INDTAX);
                        indTaxYears = XmlHelpers.GetXmlGroupItems(reader: reader, tag: TAGS.INDTAX_YEAR, hasId: false);
                    }

                // ... then analyse the info:
                GetCountryInfo(country.cao, ctry);

                // note that sys-id can be actually the system's id (guid) or the system's name ...
                string sysId = GetSysInfo(sysIdentifier, syss, country, out string sysWarning);
                if (sysWarning != null)
                {
                    ReportError(communicator, path, sysWarning, false);
                }

                // if no data was defined, try to get the best match
                if (string.IsNullOrEmpty(dataIdentifier))
                {
                    foreach (Dictionary <string, string> sysdata in sysDatas.Values)
                    {
                        if (sysdata[TAGS.SYS_ID] == sysId && sysdata[TAGS.BEST_MATCH].Equals("yes", StringComparison.InvariantCultureIgnoreCase))
                        {
                            dataIdentifier = sysdata[TAGS.DATA_ID];
                            break;
                        }
                    }

                    // if still no data, then issue error
                    if (string.IsNullOrEmpty(dataIdentifier))
                    {
                        ReportError(communicator, path, "No dataset provided and no best match was found for this system.", true);
                    }
                }

                // ... note that dataIdentifier can be actually the data's id (guid) or the data's name ...
                string dataId = GetDataInfo(dataIdentifier, datas, country, out string dataWarning);

                if (dataWarning != null)
                {
                    ReportError(communicator, path, dataWarning, false);
                }

                GetPolInfo(sysId, pols, sysPols, refPols, ignorePrivate, country.cao, out List <string> polErrors, readComment);
                foreach (string polError in polErrors)
                {
                    ReportError(communicator, path, polError);
                }

                GetFunInfo(sysId, funs, sysFuns, refPols, ignorePrivate, country.cao, out List <string> funErrors, readComment);
                foreach (string funError in funErrors)
                {
                    ReportError(communicator, path, funError);
                }

                GetParInfo(sysId, pars, sysPars, ignorePrivate, country.cao, out List <string> parErrors, readComment);
                foreach (string parError in parErrors)
                {
                    ReportError(communicator, path, parError);
                }

                GetUpIndInfo(upInds, upIndYears, country);

                GetExtensionInfo(sysId, dataId, extSwitch, localExt, extPol, extFun, extPar, country);

                if (!GetIndTaxInfo(indTaxes, indTaxYears, country))
                {
                    ReportError(communicator, path, $"No values for year {country.data.indirectTaxTableYear} found in Indirect Taxes Table");
                }

                return(country);
            }
            catch (Exception exception)
            {
                throw new Exception($"Failure reading file {path}{Environment.NewLine}{exception.Message}");
            }
        }
Exemplo n.º 5
0
        private static void GetPolInfo(string sysId,
                                       Dictionary <string, Dictionary <string, string> > pols,
                                       Dictionary <string, Dictionary <string, string> > sysPols,
                                       Dictionary <string, Dictionary <string, string> > refPols,
                                       bool ignorePrivate,
                                       ExeXml.CAO cao, out List <string> errors, bool readComment = false)
        {
            errors = new List <string>();

            foreach (Dictionary <string, string> sp in sysPols.Values)       // loop over <SYS_POLs>
            {
                if (sp.ContainsKey(TAGS.SYS_ID) && sp[TAGS.SYS_ID] == sysId) // consider only <SYS_POL> with the appropriate <SYS_ID>
                {
                    ExeXml.Pol pol   = new ExeXml.Pol();
                    string     polId = sp.GetOrEmpty(TAGS.POL_ID);

                    bool?on = DefPar.Value.IsOn(sp.GetOrEmpty(TAGS.SWITCH));
                    if (on == null)
                    {
                        continue;             // ignore if switched to n/a
                    }
                    pol.on = on == true;

                    pol.order = GetOrder(sp, out string orderError);
                    if (orderError != null)
                    {
                        errors.Add(orderError);
                    }

                    if (polId == string.Empty)
                    {
                        continue;
                    }

                    string rPolId = polId; // reference policies: the info must come from the referenced pol, but the id from the reference
                    if (refPols.ContainsKey(polId))
                    {
                        rPolId = refPols[polId].GetOrEmpty(TAGS.REFPOL_ID);
                    }
                    if (pols.ContainsKey(rPolId))
                    {
                        pol.name = pols[rPolId].GetOrEmpty(TAGS.NAME); // get policy-name from <POLs>
                        if (readComment)
                        {
                            pol.comment = XmlHelpers.RemoveCData(pols[rPolId].GetOrEmpty(TAGS.COMMENT));
                        }

                        if (ignorePrivate)
                        {
                            string priv = pols[rPolId].GetOrEmpty(TAGS.PRIVATE);
                            if (priv != null && priv == DefPar.Value.YES)
                            {
                                continue;                                           // ignore if private
                            }
                        }
                    }

                    cao.pols.Add(polId, pol);
                }
            }
        }