PageRenderTime 56ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/MercerPoC/src/in/lnt/validations/FormValidator_CSC.java

https://bitbucket.org/jwala/mercer_api_local
Java | 904 lines | 668 code | 108 blank | 128 comment | 214 complexity | 150ffd7ef30a69bd79703aebf6b93dd0 MD5 | raw file
  1. package in.lnt.validations;
  2. import java.io.ByteArrayInputStream;
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.HashSet;
  6. import java.util.Iterator;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.Set;
  10. import java.util.regex.Pattern;
  11. import org.apache.commons.lang3.EnumUtils;
  12. import org.apache.commons.lang3.StringUtils;
  13. import org.json.JSONArray;
  14. import org.json.JSONObject;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. import com.fasterxml.jackson.databind.JsonNode;
  18. import com.fasterxml.jackson.databind.ObjectMapper;
  19. import com.fasterxml.jackson.databind.node.ArrayNode;
  20. import com.fasterxml.jackson.databind.node.JsonNodeType;
  21. import com.fasterxml.jackson.databind.node.ObjectNode;
  22. import com.lti.mosaic.parser.driver.ExpressionEvalutionDriver;
  23. import in.lnt.constants.Constants;
  24. import in.lnt.enums.ValidationTypes;
  25. import in.lnt.exceptions.CustomStatusException;
  26. import in.lnt.parser.CSVParser;
  27. import in.lnt.service.db.DBUtils;
  28. import in.lnt.utility.general.DataUtility;
  29. import in.lnt.utility.general.JsonUtils;
  30. import in.lnt.validations.evaluator.APIExpressionEvaluator;
  31. public class FormValidator_CSC {
  32. private static final Logger logger = LoggerFactory.getLogger(FormValidator_CSC.class);
  33. ObjectMapper mapper = new ObjectMapper();
  34. List<String> uuidList = new ArrayList<>();
  35. static Pattern VALID_EMAIL_ADDRESS_REGEX =
  36. Pattern.compile("^(.+)@(.+)$", Pattern.CASE_INSENSITIVE);
  37. static Pattern VALID_PHONE_NUMBER_REGEX =
  38. Pattern.compile("^(\\(?\\+?[0-9]*\\)?)?[0-9_\\- \\(\\)]*$", Pattern.CASE_INSENSITIVE);
  39. // ^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$
  40. public JsonNode parseAndValidate_CrossSectionCheck(String entitiesJson, boolean isMDARequest) throws Exception {
  41. //logger.info(String.format("%s %s", Constants.INTIATE ,Constants.LOG_PARSEANDVALIDATE));
  42. JsonNode resultNode = null;
  43. ArrayNode entityArr = null;
  44. ArrayNode arr = null;
  45. JsonNode resultEntiryNode=null;
  46. HashMap<String,JsonNode> dimMap = new HashMap<>();
  47. JsonNode dataNode=null;
  48. JsonNode contextDataNode=null;
  49. JsonNode entityNode=null;
  50. resultNode=mapper.createObjectNode();
  51. resultEntiryNode=null;
  52. entityArr= mapper.createArrayNode();
  53. Map.Entry<String, JsonNode> entry = null;
  54. Map.Entry<String, JsonNode> entry1 = null;
  55. ArrayNode entitiesNode = mapper.readValue(entitiesJson, ArrayNode.class); // "Entities" node
  56. JsonNode sectionsNode = null; // "sections"
  57. // PE-7056 contexDataKeys and otherDataKeys.are append together in otherAndContextKeys.
  58. List<String> otherAndContextKeys = new ArrayList<>();
  59. //logger.info(String.format("nodetype...%d", entitiesNode.size()));
  60. HashMap<String, JsonNode> dataMap = new HashMap<>();
  61. Iterator<Map.Entry<String, JsonNode>> it =null;
  62. Iterator<Map.Entry<String, JsonNode>> contextIt = null;
  63. // Fixed along with PE-8070
  64. List<ArrayList<JsonNode>> columnNodeList_Master = null;
  65. List<ArrayList<HashMap<String, JsonNode>>> dataMap2_Sections = null;
  66. Set<String> metaDataColumnsOnly;
  67. APIExpressionEvaluator.df.setMaximumFractionDigits(16);
  68. APIExpressionEvaluator.df.setMinimumFractionDigits(1);
  69. /************ Iterating entities *****************/
  70. for(int i=0;i<entitiesNode.size();i++) {
  71. entityNode = entitiesNode.get(i);
  72. resultEntiryNode = mapper.createObjectNode();
  73. dataNode = mapper.createArrayNode(); //entityNode.get(Constants.DATA);
  74. sectionsNode = entityNode.get(Constants.SECTIONS);
  75. contextDataNode = entityNode.get(Constants.CONTEXTDATAKEY);
  76. metaDataColumnsOnly = new HashSet<>();
  77. /*
  78. * 1. Populate "dataMap" with "contextData" object
  79. */
  80. if (contextDataNode != null && !contextDataNode.toString().equals("")) {
  81. contextIt = contextDataNode.fields();
  82. while (contextIt.hasNext()) {
  83. entry = contextIt.next();
  84. JsonNode value = JsonUtils.isNullNode(entry.getValue())?null:entry.getValue();
  85. if (entry.getValue().getNodeType() != JsonNodeType.OBJECT // PE-8070
  86. && entry.getValue().getNodeType() != JsonNodeType.ARRAY) {
  87. dataMap.put(Constants.CONTEXTDATAKEY + "." + entry.getKey().trim(), value);
  88. //PE-7056
  89. otherAndContextKeys.add(Constants.CONTEXTDATAKEY + "." + entry.getKey().trim());
  90. } else if (value.getNodeType() == JsonNodeType.ARRAY) {
  91. Iterator<Map.Entry<String, JsonNode>> arrIt = value.get(0).fields();
  92. while (arrIt.hasNext()) {
  93. entry1 = arrIt.next();
  94. dataMap.put(Constants.CONTEXTDATAKEY + ".industry." + entry1.getKey().trim(),
  95. entry1.getValue());
  96. //PE-7056
  97. otherAndContextKeys.add(Constants.CONTEXTDATAKEY + ".industry." + entry1.getKey().trim());
  98. }
  99. } else {
  100. dataMap = new FormValidator().parseJsonObjectMap(entry.getKey(), value, dataMap,
  101. Constants.CONTEXTDATAKEY, null,otherAndContextKeys);
  102. }
  103. }
  104. entry = null;
  105. }
  106. /*
  107. * 1. Ended
  108. */
  109. /*********** 2. Iterating sections ******************/
  110. /* Generate :
  111. * dataMap2_Sections => [[{Q1=a,Q2=b},{Q1=x,Q2=y}],[{Q6=q},{Q6=r},{Q6=s}]]
  112. */
  113. columnNodeList_Master = new ArrayList<>();
  114. dataMap2_Sections = new ArrayList<>();
  115. //Creating a ExpressionEvalutionDriver at a request level(Per Entity (Eg. Employee section))
  116. ExpressionEvalutionDriver expressionEvalutionDriver = new ExpressionEvalutionDriver();
  117. APIExpressionEvaluator apiExpressionEvaluator = new APIExpressionEvaluator(expressionEvalutionDriver);
  118. logger.debug("parseAndValidate_CrossSectionCheck >> ExpressionEvaluatorDriver Cache : {}",
  119. apiExpressionEvaluator.getExpressionEvaluatorDriver().getAggregateFunctionCache());
  120. //Set Column - data type mapping - PE
  121. apiExpressionEvaluator.setColumnDataTypeMapping(new HashMap<String,String>());
  122. for (int sctnCtr=0; sctnCtr<sectionsNode.size(); sctnCtr++){
  123. ArrayList<HashMap<String, JsonNode>> dataMap2 = new ArrayList<>();
  124. /******** 2.1 Iterating columns : Generate columnNodeList_Master for all sections ********/
  125. ArrayList<JsonNode> columnNodeList_Section = new ArrayList<>();
  126. JsonNode sectionNode_sectionStructure_columns = sectionsNode.get(sctnCtr).get(Constants.SECTION_STRUCTURE).get(Constants.COLUMNS);
  127. for(int clmCtr = 0; clmCtr<sectionNode_sectionStructure_columns.size(); clmCtr++){
  128. columnNodeList_Section.add(sectionNode_sectionStructure_columns.get(clmCtr));
  129. // SG : Start PE-7056 Expression should not executed if columns are not present in MetaData.
  130. // Populate "metaDataColumnsOnly"
  131. if(!JsonUtils.isNullOrBlankOrNullNode(
  132. sectionNode_sectionStructure_columns.get(clmCtr).get(Constants.CODE))) {
  133. metaDataColumnsOnly.add(
  134. sectionNode_sectionStructure_columns.get(clmCtr).get(Constants.CODE).asText());
  135. // PE-8070 : Add dimensions also in "metaDataColumnsOnly"
  136. if(sectionNode_sectionStructure_columns.get(clmCtr).has(Constants.DIMENSIONS)) {
  137. ArrayNode dimensionArray = (ArrayNode)sectionNode_sectionStructure_columns.get(clmCtr).get("dimensions");
  138. for(int j = 0; j<dimensionArray.size(); j++) {
  139. if(!JsonUtils.isNullOrBlankOrNullNode(dimensionArray.get(j))) {
  140. metaDataColumnsOnly.add(sectionNode_sectionStructure_columns.get(clmCtr).get(Constants.CODE).asText()
  141. +"."+dimensionArray.get(j).asText());
  142. }
  143. }
  144. dimensionArray = null;
  145. }
  146. }
  147. // End PE-7056
  148. }
  149. columnNodeList_Master.add(columnNodeList_Section);
  150. /******** 2.1 Ended ********/
  151. for (ArrayList<JsonNode> columnNodeList : columnNodeList_Master) {
  152. for (JsonNode columnNode : columnNodeList) {
  153. if ((null != columnNode.get(Constants.CODE)
  154. && !StringUtils.isBlank(columnNode.get(Constants.CODE).asText()))
  155. && (null != columnNode.get(Constants.DATA_TYPE))) {
  156. apiExpressionEvaluator.getColumnDataTypeMapping().put(
  157. columnNode.get(Constants.CODE).asText(),
  158. columnNode.get(Constants.DATA_TYPE).asText());
  159. /**
  160. * @author Akhileshwar
  161. * PE-7045
  162. */
  163. // dimension map created
  164. if (columnNode.get(Constants.DIMENSIONS) != null) {
  165. for (JsonNode dimensioNode : columnNode.get(Constants.DIMENSIONS)) { // Code by Vivek
  166. apiExpressionEvaluator.getColumnDataTypeMapping().put(columnNode.get(Constants.CODE).asText() +Constants.DOT + dimensioNode.asText(),
  167. columnNode.get(Constants.DATA_TYPE).asText());
  168. }
  169. dimMap.put(columnNode.get(Constants.CODE).asText(),columnNode.get(Constants.DIMENSIONS));
  170. }
  171. }
  172. }
  173. }
  174. /*********** Iterating Data : Generate DataMap for all sections ******************/
  175. dataNode = mapper.createArrayNode();
  176. for(int dataCtr = 0; dataCtr<sectionsNode.get(sctnCtr).get(Constants.DATA).size(); dataCtr++){
  177. HashMap<String, JsonNode> dataMapTmp = new HashMap<>();
  178. // PE-7506
  179. // TODO Check if these 2 variables can be declared above.
  180. JsonNode dNode = sectionsNode.get(sctnCtr).get(Constants.DATA).get(dataCtr);
  181. JsonNode sect_sectStruc_col = sectionsNode.get(sctnCtr).get(Constants.SECTION_STRUCTURE).get(Constants.COLUMNS);
  182. // for(int k=0;k<dNode.size();k++) {
  183. it = dNode.fields();
  184. while (it.hasNext()) {
  185. entry = it.next();
  186. JsonNode value = JsonUtils.isNullNode(entry.getValue()) ? null : entry.getValue();
  187. if(null != value) {
  188. if (value.getNodeType() != JsonNodeType.OBJECT) {
  189. dataMapTmp.put(entry.getKey().trim(), value);
  190. } else {
  191. dataMapTmp = new FormValidator().parseJsonObjectMap(entry.getKey(), value, dataMapTmp,
  192. null, sect_sectStruc_col,null); // PE-7506
  193. }
  194. }else{
  195. dataMapTmp.put(entry.getKey().trim(), null);
  196. }
  197. value = null;
  198. }
  199. ((ArrayNode)dataNode).add(dNode);
  200. // }
  201. for (JsonNode columnNode : sect_sectStruc_col) {
  202. if (!JsonUtils.isNullOrBlankOrNullNode(columnNode.get(Constants.DIMENSIONS))) {
  203. dimMap.put(columnNode.get(Constants.CODE).asText(), columnNode.get(Constants.DIMENSIONS));
  204. }
  205. // PE-8292 Add null to dataMapTmp if Question is present in metadata-json but absent in data-json
  206. if (!JsonUtils.isNullOrBlankOrNullNode(columnNode.get(Constants.CODE))
  207. && !dataMapTmp.containsKey(columnNode.get(Constants.CODE).asText())) {
  208. dataMapTmp.put(columnNode.get(Constants.CODE).asText().trim(), null);
  209. }
  210. }
  211. dataMapTmp= new FormValidator().updateDataMapWithEmptyDimension(dataMapTmp,dimMap);
  212. dataMap2.add(dataMapTmp);
  213. dNode = null;
  214. sect_sectStruc_col = null;
  215. dataMapTmp = null;
  216. }
  217. //Making csv out of JSON single level
  218. if(null != dataNode) {
  219. //logger.info(dataNode.toString());
  220. JSONArray myArr = new JSONArray(dataNode.toString());
  221. Set<String> keyList = new HashSet();
  222. for (int j = 0; j < myArr.length(); j++) {
  223. JSONObject json = myArr.getJSONObject(j);
  224. Iterator<String> keys = json.keys();
  225. while (keys.hasNext()) {
  226. keyList.add(keys.next());
  227. }
  228. }
  229. CSVParser.parseFile(new ByteArrayInputStream(
  230. (JsonUtils.rowToString(new JSONArray(keyList)) + JsonUtils.toString(new JSONArray(keyList), myArr))
  231. .toString().getBytes("UTF-8")));
  232. }
  233. uuidList.add(apiExpressionEvaluator.getExpressionEvaluatorDriver().setCsvData(CSVParser.dataForAggregation, null));
  234. dataMap2_Sections.add(dataMap2);
  235. }
  236. /*********** 2. Ended ******************/
  237. // //Start PE-7056 Expression should not executed if columns are not present in MetaData.
  238. if(!otherAndContextKeys.isEmpty()){
  239. metaDataColumnsOnly.addAll(otherAndContextKeys);
  240. }
  241. // //End PE-7056
  242. /*********** 3. Iterating sections and perform validations ***********/
  243. JsonNode sectionNodeNum = null;
  244. ArrayNode sectionArray = mapper.createArrayNode();
  245. for (int sctnCtr=0; sctnCtr<sectionsNode.size(); sctnCtr++){
  246. sectionNodeNum = mapper.createObjectNode();
  247. arr = mapper.createArrayNode();
  248. /*********** 3.1 Generate DataMap for the section (not including self dataMap values) ***********/
  249. int c=0;
  250. Map<String, Integer> duplicateChkMap = new HashMap<>();
  251. for(ArrayList<HashMap<String, JsonNode>> dataMap2: dataMap2_Sections){
  252. if(sctnCtr != c){
  253. for(HashMap<String, JsonNode> hm : dataMap2 ){
  254. for(Map.Entry<String,JsonNode> e : hm.entrySet()){
  255. dataMap.put(e.getKey(), e.getValue()); // Put key in dataMap
  256. if(duplicateChkMap.containsKey(e.getKey())){
  257. int val= Integer.parseInt(duplicateChkMap.get(e.getKey()).toString());
  258. duplicateChkMap.put(e.getKey(), val+1);
  259. }else{
  260. duplicateChkMap.put(e.getKey(), 1);
  261. }
  262. }
  263. }
  264. }
  265. c++;
  266. }
  267. // TODO Optimize code by merging below for in above loop
  268. for(Map.Entry<String, Integer> e : duplicateChkMap.entrySet()){
  269. if(e.getValue()!=1){
  270. dataMap.remove(e.getKey());
  271. }
  272. }
  273. /*********** 3.1 Ended ******************/
  274. /*********** 3.2 Iterating Rows (populating self dataMap values) and perform validations ***********/
  275. for(int dataCtr = 0; dataCtr<sectionsNode.get(sctnCtr).get(Constants.DATA).size(); dataCtr++){
  276. HashMap<String, JsonNode> dataMapFinal = new HashMap<>();
  277. // Put all other section dataMap
  278. dataMapFinal.putAll(dataMap);
  279. // Put all self section dataMap
  280. dataMapFinal.putAll(dataMap2_Sections.get(sctnCtr).get(dataCtr));
  281. //logger.debug(String.format("dataMap..%s" , dataMap));
  282. dataNode = sectionsNode.get(sctnCtr).get(Constants.DATA);
  283. //7045 dimMap added and 7056 metaDataColumnsOnly
  284. resultNode = validate(dataMapFinal, columnNodeList_Master.get(sctnCtr), dataNode.get(dataCtr),
  285. apiExpressionEvaluator, duplicateChkMap,isMDARequest,dimMap, new ArrayList(metaDataColumnsOnly));
  286. arr.add(resultNode);
  287. dataMapFinal.clear();
  288. } // SECTION END
  289. /*********** 3.2 Ended ***********/
  290. ((ObjectNode) (sectionNodeNum)).set(Constants.SECTIONCODE, sectionsNode.get(sctnCtr).get(Constants.SECTIONCODE));
  291. ((ObjectNode) (sectionNodeNum)).set(Constants.DATA, arr);
  292. ((ArrayNode) sectionArray).add(sectionNodeNum);
  293. }
  294. /*********** 3. Ended ***********/
  295. ((ObjectNode) resultEntiryNode).set(Constants.SECTIONS, sectionArray); // Add sections
  296. if(null != contextDataNode)
  297. ((ObjectNode) (resultEntiryNode)).set(Constants.CONTEXTDATAKEY, contextDataNode); // Add ContextData
  298. entityArr.add(resultEntiryNode);
  299. for (String uuid : uuidList) {
  300. apiExpressionEvaluator.getExpressionEvaluatorDriver().removeCsvData(uuid);
  301. }
  302. metaDataColumnsOnly = null;
  303. //PE-8070 end
  304. }
  305. resultNode=mapper.createObjectNode().set("entities", entityArr);
  306. //logger.info(String.format("%s %s", Constants.EXIT ,Constants.LOG_PARSEANDVALIDATE));
  307. return resultNode;
  308. }
  309. public JsonNode validate(HashMap<String, JsonNode> dataMap, ArrayList<JsonNode> columnNodeList,
  310. JsonNode dataNode, APIExpressionEvaluator apiExpressionEvaluator, Map<String, Integer> cscDuplicateChkMap, boolean isMDARequest,
  311. HashMap<String, JsonNode> dimMap, List<String> metaDataColumnsOnly ) throws Exception { //7045
  312. //logger.info(String.format("%s %s", Constants.INTIATE ,Constants.LOG_VALIDATE));
  313. JsonNode validationNode = null;
  314. ObjectNode obj = null;
  315. String code = "";
  316. ArrayNode arr = null;
  317. JsonNode nodeDTObject = null;
  318. JsonNode dnCodeObject = null;
  319. Map<String, String> incorrectDataType = new HashMap<>();
  320. String result = null;
  321. JsonNode validationObjNode = null;
  322. ArrayList<ObjectNode> predefinedObjList = null;
  323. List<ObjectNode> rangeOrSeqObjList = null;
  324. ArrayList<String> dimList=null;
  325. ArrayList<ObjectNode> seqCheckList=null;
  326. //PE-5643 by default true because for true type do not fire validations.
  327. boolean isOptionType = true;
  328. JsonNode validationOBJ = null;
  329. JsonNode dimNode = null;
  330. int endPoint = Constants.ENDPOINT_DEFAULT;
  331. JsonNode questionType = null; //Added for 8916 Remove %
  332. try {
  333. if(isMDARequest) {
  334. endPoint = Constants.ENDPOINT_PERFORM_DEFAULT_ACTIONS;
  335. }
  336. if (columnNodeList != null && columnNodeList.size() > 0) {
  337. arr = mapper.createArrayNode();
  338. for (JsonNode node : columnNodeList) {
  339. code = node.get(Constants.CODE).asText();
  340. JsonNode currentDataMapCol = null;
  341. if (dataNode != null ) {
  342. //Added for 8916 Remove %
  343. questionType = node.get(Constants.QUESTION_TYPE);
  344. if(!JsonUtils.isNullOrBlankOrNullNode(questionType) && questionType.asText().equals(Constants.PERCENTAGE)){
  345. if (null != dataMap && !JsonUtils.isNullOrBlankOrNullNode(dataMap.get(code)) && dataNode.get(code) != null) {
  346. String percentageValue = dataMap.get(code).asText().trim();
  347. if(!percentageValue.isEmpty() && percentageValue.endsWith("%")){
  348. percentageValue = percentageValue.substring(0, percentageValue.length()-1);
  349. dataMap.put(code, mapper.readTree(percentageValue));
  350. ((ObjectNode) dataNode).put(code, mapper.readTree(percentageValue));
  351. }
  352. }
  353. } //PE -5216 and PE-5643 Check for drop down options exist in metadata or in database.
  354. if (questionType != null
  355. && ( questionType.asText().equals("dropdown") ||
  356. questionType.asText().equals("radio_buttons") )) {
  357. //logger.info(String.format("Question type is %s", node.get("questionType").asText()));
  358. // PE-8070 Clear & Prepare outputJson for dimensions
  359. if(!JsonUtils.isNullOrBlankOrNullNode(dataNode.get(code)) && dataNode.get(code).getNodeType()==JsonNodeType.OBJECT) {
  360. Iterator<String> it = dataNode.get(code).fieldNames();
  361. String dimensionKey = null;
  362. while(null!=it && it.hasNext() ) {
  363. dimensionKey = it.next();
  364. isOptionType = checkAnswerExists(node, dataNode.get(code).get(dimensionKey));
  365. // TODO Further task (Make it a function)
  366. if ( ! isOptionType ) {
  367. // PE-8397
  368. // // Implementation start PE : 5643
  369. // // Clear the value anyways if checkAnswerExists==false
  370. if(isMDARequest)
  371. {
  372. ((ObjectNode) (dataNode.get(code))).put(dimensionKey, "");
  373. }
  374. // ((ObjectNode) (dataNode.get(code))).put(dimensionKey, "");
  375. // // Implementation end PE : 5643
  376. // Generate error for dimension in format : Question1.Dimension1
  377. obj = apiExpressionEvaluator.prepareOutputJson(null, null, null, ValidationTypes.DROPDOWN,
  378. code+"."+dimensionKey, null, null,node.has(Constants.DISPLAYLABEL) ? node.get(Constants.DISPLAYLABEL).asText() : null);
  379. }
  380. if (obj != null) {
  381. arr.add(obj);
  382. obj = null;
  383. }
  384. }
  385. // Clear & Prepare outputJson for non-dimensional questions (ie. simple values)
  386. } else {
  387. isOptionType = checkAnswerExists(node, dataNode.get(code));
  388. if ( ! isOptionType ) {
  389. // PE-8397
  390. // // Implementation start PE : 5643
  391. // // Clear the value anyways if checkAnswerExists==false
  392. if (isMDARequest) {
  393. ((ObjectNode) (dataNode)).put(code, "");
  394. }
  395. // ((ObjectNode) (dataNode)).put(code, "");
  396. // // Implementation end PE : 5643
  397. obj = apiExpressionEvaluator.prepareOutputJson(null, null, null, ValidationTypes.DROPDOWN,
  398. code, null, null,node.has(Constants.DISPLAYLABEL) ? node.get(Constants.DISPLAYLABEL).asText() : null);
  399. }
  400. if (obj != null) {
  401. arr.add(obj);
  402. obj = null;
  403. }
  404. }
  405. }
  406. if(null != dataMap && !JsonUtils.isNullOrBlankOrNullNode(dataMap.get(code))){
  407. currentDataMapCol = dataMap.get(code);
  408. }
  409. //PE-9490 Round off upto 2 precision places for money question type
  410. if(questionType != null && questionType.asText().equals(Constants.MONEY)) {
  411. nodeDTObject = node.get(Constants.DATA_TYPE);
  412. if (!JsonUtils.isNullOrBlankOrNullNode(nodeDTObject)) {
  413. dnCodeObject = dataNode.get(code);
  414. if (!JsonUtils.isNullOrBlankOrNullNode(dnCodeObject)
  415. && !StringUtils.isEmpty(dnCodeObject.asText().trim())) {
  416. incorrectDataType = new FormValidator().dataTypeCheck(dataMap, dataNode, code,
  417. nodeDTObject, dnCodeObject, false, null, null);
  418. boolean flag = Boolean.parseBoolean(incorrectDataType.get("dataTypeFlag"));
  419. if(flag && null != currentDataMapCol && dataNode.get(code) != null) {
  420. String colStringVal = currentDataMapCol.asText().trim();
  421. double colDoubleVal = currentDataMapCol.asDouble();
  422. if(colStringVal.contains(".")) {
  423. //RoundOff the value and return error object if it has more than 2 precision places
  424. obj = DataUtility.roundOffMoneyQuestionType(dataMap, dataNode, obj, code, nodeDTObject.asText(), colStringVal, colDoubleVal);
  425. }
  426. }
  427. }
  428. }
  429. }
  430. // PE 9145 : Clear code value in MDA in case of data type error
  431. if(isMDARequest)
  432. {
  433. nodeDTObject = node.get(Constants.DATA_TYPE);
  434. if (!JsonUtils.isNullOrBlankOrNullNode(nodeDTObject)) {
  435. dnCodeObject = dataNode.get(code);
  436. if (isMDARequest && !JsonUtils.isNullOrBlankOrNullNode(dnCodeObject)
  437. && !StringUtils.isEmpty(dnCodeObject.asText().trim())) {
  438. incorrectDataType = new FormValidator().dataTypeCheck(dataMap, dataNode, code,
  439. nodeDTObject, dnCodeObject, false, null, null);
  440. if (!Boolean.parseBoolean(incorrectDataType.get("dataTypeFlag"))) {
  441. ((ObjectNode) (dataNode)).put(code, "");
  442. }
  443. }
  444. }
  445. }
  446. // PE 9145 end
  447. if (node.get(Constants.VALIDATIONS) != null && node.get(Constants.VALIDATIONS).size() > 0) {
  448. for (int i = 0; i < node.get(Constants.VALIDATIONS).size(); i++) {
  449. boolean rangeAlertFlag = false;
  450. try {
  451. validationNode = node.get(Constants.VALIDATIONS).get(i);
  452. if (validationNode.get(Constants.VALIDATION_TYPE) != null
  453. && EnumUtils.isValidEnum(ValidationTypes.class,
  454. validationNode.get(Constants.VALIDATION_TYPE).asText().toUpperCase())) {
  455. switch (ValidationTypes
  456. .valueOf(validationNode.get(Constants.VALIDATION_TYPE).asText().toUpperCase())) {
  457. case REQUIRED:
  458. // PE - 7241
  459. predefinedObjList = FormValidator.validatePredefinedValidation(dataNode,node,validationNode,dataMap,null,Constants.REQUIRED);
  460. break;
  461. case PHONE:
  462. // PE - 7241
  463. predefinedObjList = FormValidator.validatePredefinedValidation(dataNode,node,validationNode,null,null,Constants.PHONE);
  464. break;
  465. case EMAIL:
  466. // PE - 7241
  467. predefinedObjList = FormValidator.validatePredefinedValidation(dataNode,node,validationNode,null,null,Constants.EMAIL);
  468. break;
  469. case RANGE:
  470. rangeOrSeqObjList = apiExpressionEvaluator.prepareRangeObject(dataMap, validationNode, node,dataNode);
  471. //rangeAlertFlag = true;
  472. break;
  473. case RANGEVALIDATIONREFTABLE:
  474. rangeOrSeqObjList = apiExpressionEvaluator.prepareRefernceRangeObject(dataMap, validationNode,node, dataNode);
  475. //rangeAlertFlag = true;
  476. break;
  477. case EXPRESSION:
  478. obj = apiExpressionEvaluator.expressionEvaluator(dataMap, validationNode, node,
  479. dataNode, cscDuplicateChkMap,columnNodeList, metaDataColumnsOnly, endPoint);
  480. break;
  481. case ELIGIBILITY:
  482. arr.addAll(apiExpressionEvaluator.checkValidity(dataMap, validationNode, node,
  483. dataNode, isMDARequest,metaDataColumnsOnly));
  484. break;
  485. /**
  486. * @author Akhileshwar
  487. * PE-7045
  488. */
  489. case SEQUENTIALCHECK://PE-7989 metaDataColumnsOnly added in method signature
  490. rangeOrSeqObjList = apiExpressionEvaluator.performSequentialCheck(dataMap, validationNode, node,
  491. dataNode,dimMap,apiExpressionEvaluator.getColumnDataTypeMapping(), false, metaDataColumnsOnly);
  492. break;
  493. default:
  494. }
  495. } else {
  496. result = Constants.MANDATORY_VALIDATIONTYPE;
  497. obj = apiExpressionEvaluator.prepareOutputJson(null, null, result, null, null, null,
  498. null, null);
  499. }
  500. if (obj != null) {
  501. arr.add(obj);
  502. obj = null;
  503. }
  504. if(rangeOrSeqObjList!=null)
  505. {
  506. for(int j=0;j<rangeOrSeqObjList.size();j++)
  507. {
  508. arr.add(rangeOrSeqObjList.get(j));
  509. }
  510. rangeOrSeqObjList=null;
  511. }
  512. if((null != predefinedObjList) && (predefinedObjList.size() > 0)){
  513. arr.addAll(predefinedObjList);
  514. predefinedObjList = null;
  515. }
  516. // PE-8353 : Log all exceptions and don't throw outside
  517. } catch (CustomStatusException e) {
  518. // if(e.getHttpStatus()==Constants.HTTPSTATUS_400) {
  519. logger.info(JsonUtils.updateErrorNode(e, mapper.createObjectNode()).toString());
  520. // }
  521. } catch(Exception ex) {
  522. logger.info(ex.getMessage());
  523. }
  524. if(arr != null && arr.size() > 0) {
  525. //for(int valCnt=0; valCnt<node.get(Constants.VALIDATIONS).size(); valCnt++) {
  526. if(null!=node.get(Constants.VALIDATIONS)) {
  527. validationOBJ = validationNode;
  528. // Check if MDA action available
  529. if (null!=validationOBJ && null != validationOBJ.get(Constants.MDA)
  530. && !validationOBJ.get(Constants.MDA).asText().equals("")
  531. && !validationOBJ.get(Constants.VALIDATION_TYPE).asText().equals("expression"))
  532. {
  533. //if(rangeAlertFlag == true){
  534. for(JsonNode jnode : arr){
  535. //System.out.println(jnode.get(Constants.VALIDATION_TYPE)+"------"+);
  536. if(Constants.ERROR.equals(jnode.get(Constants.ERROR_TYPE).asText()) &&
  537. !JsonUtils.isNullOrBlankOrNullNode(jnode.get(Constants.VALIDATION_TYPE)) &&
  538. validationOBJ.get(Constants.VALIDATION_TYPE).asText().equals(jnode.get(Constants.VALIDATION_TYPE).asText())){
  539. rangeAlertFlag = true;
  540. break;
  541. }
  542. }
  543. //}
  544. if(rangeAlertFlag == true){
  545. // MDA = exclude_row
  546. if (validationOBJ.get(Constants.MDA).asText().equalsIgnoreCase(Constants.EXECLUE_ROW)) {
  547. //((ObjectNode) (dataNode)).put(Constants.EXCLUDE_FLAG, "Y");
  548. List<String> columnNodeList_Section = new ArrayList<>();
  549. //Getting columns in current section PE-7771
  550. for(int index = 0; index < columnNodeList.size(); index++){
  551. columnNodeList_Section.add(columnNodeList.get(index).get(Constants.CODE).asText());
  552. }
  553. if(columnNodeList_Section != null && columnNodeList_Section.contains(Constants.EXCLUDE_FLAG)){//PE-7771
  554. ((ObjectNode) (dataNode)).put(Constants.EXCLUDE_FLAG, Constants.ANSWER_YES);
  555. }
  556. // MDA = clear_value
  557. } else if (validationOBJ.get(Constants.MDA).asText().equalsIgnoreCase(Constants.CLEAR_VALUE)) {
  558. ((ObjectNode) (dataNode)).put(code, "");
  559. } else {//7044 condition added
  560. String responseData= apiExpressionEvaluator.
  561. expressionEvaluatorForMDA(dataMap, validationOBJ, node, cscDuplicateChkMap, metaDataColumnsOnly);
  562. if(node.get(Constants.DIMENSIONS)!=null)
  563. {
  564. dimList=APIExpressionEvaluator.extractDimensions(node.get(Constants.DIMENSIONS));
  565. dimNode = mapper.createObjectNode();
  566. for(String dim:dimList)
  567. {
  568. ((ObjectNode)dimNode).put(dim,responseData);
  569. }
  570. ((ObjectNode) (dataNode)).set(code, dimNode);
  571. }
  572. else{
  573. ((ObjectNode) (dataNode)).put(code, responseData);
  574. }
  575. }
  576. }
  577. }
  578. }
  579. }
  580. }
  581. // PE 9145 removed below unused code
  582. /*result = Constants.INVALID_DATATYPE_FOR_ERROR;
  583. if (null != nodeDTObject && null != dnCodeObject) {
  584. obj = apiExpressionEvaluator.prepareOutputJson(validationObjNode, node, result,
  585. ValidationTypes.dataTypeError, dnCodeObject.asText(), nodeDTObject.asText(),
  586. nodeDTObject.asText(), null);
  587. }*/
  588. if (obj != null) {
  589. arr.add(obj);
  590. obj = null;
  591. }
  592. }
  593. if (node.get("questionType") != null
  594. && node.get("questionType").asText().equals("checkboxes")) {
  595. buildCheckboxArray(dataNode,code);
  596. }
  597. }
  598. }
  599. if ((arr != null && arr.size() > 0)) {
  600. if (dataNode.get(code) != null) {
  601. ((ObjectNode) (dataNode)).set(code, dataNode.get(code));
  602. }
  603. ((ObjectNode) (dataNode)).set(Constants.VALIDATION_RESULTS, arr);
  604. arr = null;
  605. }
  606. }
  607. // PE-8353 : Log all exceptions and don't throw outside
  608. } catch (CustomStatusException e) {
  609. // if(e.getHttpStatus()==Constants.HTTPSTATUS_400) {
  610. logger.info(JsonUtils.updateErrorNode(e, mapper.createObjectNode()).toString());
  611. // }
  612. } catch(Exception ex) {
  613. logger.info(ex.getMessage());
  614. }
  615. //logger.info(String.format("%s %s", Constants.EXIT ,Constants.LOG_VALIDATE));
  616. return dataNode;
  617. }
  618. public void buildCheckboxArray(JsonNode dataNode,String code) throws Exception
  619. {
  620. if(!JsonUtils.isNullOrBlankOrNullNode(dataNode.get(code)))//PE-8704
  621. {
  622. if( dataNode.get(code).getNodeType() != JsonNodeType.OBJECT)
  623. {
  624. ArrayNode arrNode = mapper.createArrayNode();
  625. String arr1[] = null;
  626. if( !JsonUtils.isNullNode(dataNode.get(code))) {
  627. switch (dataNode.get(code).getNodeType()) {
  628. case ARRAY:
  629. for (JsonNode node : dataNode.get(code)) {
  630. arrNode.add(node);
  631. }
  632. break;
  633. case NULL:
  634. arrNode = null;
  635. break;
  636. case STRING:
  637. arr1 = dataNode.get(code).asText().split(",");
  638. if (arr1 != null && arr1.length > 0) {
  639. for (int i = 0; i < arr1.length; i++) {
  640. arrNode.add(arr1[i]);
  641. }
  642. }
  643. break;
  644. default:
  645. break;
  646. }
  647. }
  648. ((ObjectNode) (dataNode)).set(code, arrNode);
  649. }
  650. else
  651. {
  652. Iterator<Map.Entry<String, JsonNode>> it = dataNode.get(code).fields();
  653. Map.Entry<String, JsonNode> entry = null;
  654. while(it!=null && it.hasNext())
  655. {
  656. entry =it.next();
  657. if(entry!=null && entry.getValue().getNodeType()== JsonNodeType.ARRAY)
  658. {
  659. break;
  660. }
  661. ArrayNode arrNode = mapper.createArrayNode();
  662. String arr1[]=entry.getValue().asText().split(",");
  663. if(arr1!=null && arr1.length >0)
  664. {
  665. for(int i=0;i<arr1.length;i++)
  666. {
  667. arrNode.add(arr1[i]);
  668. }
  669. }
  670. ((ObjectNode)(dataNode.get(code))).set(entry.getKey(), arrNode);
  671. }
  672. }
  673. }//PE-8704
  674. else
  675. {
  676. ((ObjectNode) (dataNode)).set(code, mapper.createArrayNode());
  677. }
  678. }
  679. public String checkUniqueNessForEEID(String enetityJson) throws Exception
  680. {
  681. String isUnique="true";
  682. JsonNode entityNode=null;
  683. JsonNode sectionsNode = null;
  684. JsonNode dataNode=null;
  685. HashSet<String> eeidSet=null;
  686. ArrayNode entitiesNode = mapper.readValue(enetityJson, ArrayNode.class);
  687. for(int i=0;i<entitiesNode.size();i++) {
  688. entityNode = entitiesNode.get(i);
  689. sectionsNode = entityNode.get(Constants.SECTIONS);
  690. for (int sctnCtr=0; sctnCtr<sectionsNode.size(); sctnCtr++){
  691. eeidSet = new HashSet<>();
  692. dataNode = sectionsNode.get(sctnCtr).get(Constants.DATA);
  693. if(dataNode!=null)
  694. {
  695. for (int k = 0; k < dataNode.size(); k++) {
  696. if(dataNode.get(k).get(Constants.EMPLOYEE_EEID)!=null && !dataNode.get(k).get(Constants.EMPLOYEE_EEID).asText().equals(""))
  697. {
  698. String eeId = dataNode.get(k).get(Constants.EMPLOYEE_EEID).asText();
  699. if(!eeidSet.add(eeId))
  700. {
  701. eeidSet=null;
  702. return Constants.DUPLICATE;
  703. }
  704. }
  705. else
  706. {
  707. return Constants.MISSING;
  708. }
  709. }
  710. }
  711. }
  712. }
  713. return isUnique;
  714. }
  715. /**
  716. *
  717. * @param dropDownOptions
  718. * @param dataNode
  719. * @param code
  720. * @param key
  721. * @return boolean value
  722. */
  723. public static boolean checkAnswerExists(JsonNode dropDownOptions, JsonNode dataNode_code) throws Exception {
  724. // logger.info("Entering checkAnswerExists method "+dataNode+" code
  725. // "+code+ " key is "+ key);
  726. ArrayNode optionsArrNode = null;
  727. JsonNode dbNode = null;
  728. Map<String, String> optionsDictionary = null;
  729. Map<String, String> dbData = null;
  730. boolean found = false;
  731. boolean fromDB = false;
  732. boolean fromJson = false;
  733. // PE-8269 If value is blank, return found=true. - only for /performDefaultActions
  734. if (JsonUtils.isNullOrBlankOrNullNode(dataNode_code) || "".equals(dataNode_code.asText()) ) {
  735. return true; // Reverted temporarily due to requirement changes
  736. }
  737. dbData = new HashMap<>();
  738. optionsDictionary = new HashMap<>();
  739. if (null != dropDownOptions && null != dropDownOptions.get(Constants.OPTIONS)) {
  740. if (null != dropDownOptions.get(Constants.OPTIONS).get("items")) {
  741. optionsArrNode = (ArrayNode) dropDownOptions.get(Constants.OPTIONS).get("items");
  742. if (optionsArrNode.size() > 0)
  743. fromJson = true;
  744. }
  745. if (null != dropDownOptions.get(Constants.OPTIONS).get(Constants.REFERENCETABLE)) {
  746. dbNode = dropDownOptions.get(Constants.OPTIONS).get(Constants.REFERENCETABLE);
  747. fromDB = true;
  748. dbData = DBUtils.getRefTableData(dbNode.get(Constants.CODE).asText());
  749. }
  750. }
  751. if (fromJson) {
  752. for (int i = 0; i < optionsArrNode.size(); i++) {
  753. if (!JsonUtils.isNullOrBlankOrNullNode(optionsArrNode.get(i).get("value"))
  754. && !JsonUtils.isNullOrBlankOrNullNode(optionsArrNode.get(i).get("displayName"))) {
  755. optionsDictionary.put(optionsArrNode.get(i).get("value").asText(),
  756. optionsArrNode.get(i).get("displayName").asText());
  757. }
  758. }
  759. if (optionsDictionary.containsKey(dataNode_code.asText())) {
  760. found = true;
  761. }
  762. } else if (fromDB && dbData.containsKey(dataNode_code.asText())) {
  763. found = true;
  764. }
  765. // logger.info("Existing checkAnswerExists method ");
  766. return found;
  767. }
  768. /**
  769. *
  770. * @param dropDownOptions
  771. * @param dbOutPut
  772. * @return option value from Drop Down
  773. * PE-9734
  774. */
  775. public static String getOptionFromDropDown(JsonNode dropDownOptions, String dbOutPut) {
  776. logger.info("Entering checkOptionExists method {}", dbOutPut);
  777. ArrayNode optionsArrNode = null;
  778. Map<String, String> optionsDictionary = null;
  779. optionsDictionary = new HashMap<>();
  780. if (null != dropDownOptions && null != dropDownOptions.get(Constants.OPTIONS) &&
  781. null != dropDownOptions.get(Constants.OPTIONS).get("items")) {
  782. optionsArrNode = (ArrayNode) dropDownOptions.get(Constants.OPTIONS).get("items");
  783. for (int i = 0; i < optionsArrNode.size(); i++) {
  784. if (!JsonUtils.isNullOrBlankOrNullNode(optionsArrNode.get(i).get("value"))
  785. && !JsonUtils.isNullOrBlankOrNullNode(optionsArrNode.get(i).get("displayName"))) {
  786. optionsDictionary.put(optionsArrNode.get(i).get("displayName").asText(),
  787. optionsArrNode.get(i).get("value").asText());
  788. }
  789. }
  790. }
  791. if (null != optionsDictionary.get(dbOutPut)) {
  792. return optionsDictionary.get(dbOutPut);
  793. }
  794. return null;
  795. }
  796. }