private void ReplaceSymbolicIDs(ExeXml.AddOn addOn) { // make a Dictonary with symbolic-id as key and guid-id as value, for all functions and parameters // symbolic-ids look like this: for functions: polName_#funOrder, e.g. neg_fr_#2, for parameters: polName_#funOrder.parOrder, e.g. neg_fr_#2.2 // special case DefTU and DefIL, which look like this: polName_#tuilName[.parOrder], e.g. IlsDef_fr_#ils_dispy respectively TUDef_fr_#tu_hh_oecd_co.2 Dictionary <string, string> allIds = new Dictionary <string, string>(); foreach (var pol in infoStore.country.cao.pols.Values) { foreach (var fun in pol.funs) { string iltuName = null; // take care of special case as noted above if (fun.Value.Name.ToLower() == DefFun.DefIl.ToLower() || fun.Value.Name.ToLower() == DefFun.DefTu.ToLower()) { var np = from p in fun.Value.pars where p.Value.Name.ToLower() == DefPar.DefIl.Name.ToLower() select p; // is also 'name' for DefTU if (np.Count() > 0) { iltuName = np.First().Value.val; } } allIds.TryAdd(AddOn.ComposeSymbolicID(pol.name, fun.Value.order.ToString()), fun.Key); // allow both: special and "regular" version if (iltuName != null) { allIds.TryAdd(AddOn.ComposeSymbolicID(pol.name, iltuName), fun.Key); // e.g. TUDef_fr_#tu_hh_oecd_co and TUDef_fr_#5 } foreach (var par in fun.Value.pars) { allIds.TryAdd(AddOn.ComposeSymbolicID(pol.name, fun.Value.order.ToString(), par.Value.order), par.Key); if (iltuName != null) { allIds.TryAdd(AddOn.ComposeSymbolicID(pol.name, iltuName, par.Value.order), par.Key); } } } } foreach (var aoPol in addOn.cao.pols) { ReplaceSymbolicIDs(aoPol.Value); } ReplaceSymbolicIDs(addOn.polAOControl); void ReplaceSymbolicIDs(ExeXml.Pol pol) { foreach (var fun in pol.funs.Values) { foreach (ExeXml.Par par in fun.pars.Values) { if (allIds.ContainsKey(par.val.ToLower())) { par.val = allIds[par.val.ToLower()]; // if is a symbolic-id replace by guid-id } } } } }
private bool FindPol(ExeXml.AddOn addOn, string polName, Dictionary <string, ExeXml.Pol> pols, out ExeXml.Pol foundPol, out string foundPolID) { foreach (var p in pols) { if (p.Value.name.ToLower() == polName.ToLower()) { foundPol = p.Value; foundPolID = p.Key; return(true); } } infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{addOn.cao.shortName}: policy {polName} not found" }); foundPol = null; foundPolID = null; return(false); }
private void IntegrateAddOn(ExeXml.AddOn addOn) { // replace =cc= and =sys= ReplaceCCSys(addOn.cao.pols); ReplaceCCSys(addOn.polAOControl); // replace symbolic ids (e.g. output_std_fr_#1.1) by their GUID in the country-file ReplaceSymbolicIDs(addOn); // integrate the add-on elements by interpreting the AddOn_Pol/Func/Par functions in the ao_control policy foreach (ExeXml.Fun addOnFun in addOn.polAOControl.funs.Values.OrderBy(o => o.order)) { if (!addOnFun.on) { continue; } Description funDescription = new Description(addOn.polAOControl, addOnFun); if (addOnFun.Name.ToLower() == DefFun.AddOn_Pol.ToLower()) { IntegratePol(addOn, addOnFun, funDescription); } else if (addOnFun.Name.ToLower() == DefFun.AddOn_Func.ToLower()) { IntegrateFun(addOn, addOnFun, funDescription); } else if (addOnFun.Name.ToLower() == DefFun.AddOn_Par.ToLower()) { IntegratePar(addOnFun, funDescription); } else if (addOnFun.Name.ToLower() == DefFun.AddOn_ExtensionSwitch.ToLower()) { continue; // already handled in Control.TakeAddOnExtensionSwitches } else { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{funDescription.Get()}: invalid add-on function: {addOnFun.Name}" }); } } }
internal void IntegratePol(ExeXml.AddOn addOn, ExeXml.Fun addOnPol, Description funDescription) { string polName = null; // the name of the policy to add string linkPolName = null; // the name of the policy after or before which to add the policy bool before = true; // interpret the parameters of the AddOn_Pol function foreach (var par in addOnPol.pars.Values) { if (par.val == DefPar.Value.NA) { continue; } Description parDescription = new Description(funDescription, par); if (par.Name.ToLower() == DefPar.AddOn_Pol.Pol_Name.ToLower()) { polName = par.val; } else if (par.Name.ToLower() == DefPar.AddOn_Pol.Insert_Before_Pol.ToLower()) { linkPolName = par.val; } else if (par.Name.ToLower() == DefPar.AddOn_Pol.Insert_After_Pol.ToLower()) { linkPolName = par.val; before = false; } else if (par.Name.ToLower() == DefPar.AddOn_Pol.Allow_Duplicates.ToLower()) { } // do nothing, just allow duplicates always else { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = $"{parDescription.Get()}: unknown parameter: {par.Name}" }); } } // check for compulsory parameters if (polName == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{funDescription.Get()}: parameter {DefPar.AddOn_Pol.Pol_Name} not defined" }); return; } if (linkPolName == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{funDescription.Get()}: neither {DefPar.AddOn_Pol.Insert_Before_Pol} nor {DefPar.AddOn_Pol.Insert_After_Pol} defined" }); return; } // integrate the policy ... // ... in the country file, find the policy after or before which to integrate the policy if (!FindPol(addOn, linkPolName, infoStore.country.cao.pols, out ExeXml.Pol linkPol, out string dummy)) { return; } // ... in the add-on file, find the policy to add if (!FindPol(addOn, polName, addOn.cao.pols, out ExeXml.Pol pol, out string polID)) { return; } // ... check if policy was added before, if yes, make a clone with different ids if (infoStore.country.cao.pols.ContainsKey(polID)) { polID = Guid.NewGuid().ToString(); pol = ClonePol(pol); } // ... find an appropriate order pol.order = MakeOrder(linkPol.order, (from p in infoStore.country.cao.pols.Values select p.order).ToList(), before); // ... add the policy infoStore.country.cao.pols.Add(polID, pol); }
private void IntegrateFun(ExeXml.AddOn addOn, ExeXml.Fun addOnFun, Description funDescription) { string funID = null; // the id of the function to add string linkFunID = null; // the id of the function after or before which to add the function bool before = true; // interpret the parameters of the AddOn_Func function foreach (var par in addOnFun.pars.Values) { if (par.val == DefPar.Value.NA) { continue; } Description parDescription = new Description(funDescription, par); if (par.Name.ToLower() == DefPar.AddOn_Func.Id_Func.ToLower()) { funID = par.val; } else if (par.Name.ToLower() == DefPar.AddOn_Func.Insert_Before_Func.ToLower()) { linkFunID = par.val; } else if (par.Name.ToLower() == DefPar.AddOn_Func.Insert_After_Func.ToLower()) { linkFunID = par.val; before = false; } else { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = $"{parDescription.Get()}: unknown parameter: {par.Name}" }); } } // check for compulsory parameters if (funID == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{funDescription.Get()}: parameter {DefPar.AddOn_Func.Id_Func} not defined" }); return; } if (linkFunID == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{funDescription.Get()}: neither {DefPar.AddOn_Func.Insert_Before_Func} nor {DefPar.AddOn_Func.Insert_After_Func} defined" }); return; } // integrate the function ... // ... in the country file, find the function after or before which to integrate the function if (!FindFun(linkFunID, infoStore.country.cao.pols, funDescription, out ExeXml.Fun linkFun, out ExeXml.Pol parentPol)) { return; } // ... in the add-on file, find the function to add if (!FindFun(funID, addOn.cao.pols, funDescription, out ExeXml.Fun fun, out ExeXml.Pol dummy)) { return; } // ... check if function was added before, if yes, make a clone with different ids if (!parentPol.funs.ContainsKey(funID)) { funID = Guid.NewGuid().ToString(); fun = CloneFun(fun); } // ... find an appropriate order fun.order = MakeOrder(linkFun.order, (from f in parentPol.funs.Values select f.order).ToList(), before); // ... add the function parentPol.funs.Add(funID, fun); }