/*
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
*/
|
package com.megatim.fdxconvert.util;
|
|
import com.megatim.dynamicjsonparser.enums.TypeDonnee;
|
import com.megatim.typefichier.validator.utilities.Constantes;
|
import com.megatim.fdxconvert.exceptions.ValidatorException;
|
import com.megatim.fdxconvert.pojo.ColumnDefinition;
|
import java.io.File;
|
import java.text.Normalizer;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
import org.w3c.dom.Document;
|
import org.w3c.dom.NamedNodeMap;
|
import org.w3c.dom.Node;
|
import org.w3c.dom.NodeList;
|
|
/**
|
*
|
* @author ASUS
|
*/
|
public class ValidateurParser {
|
|
/**
|
* Méthode permettant d'extraire les éléments du validateur XML
|
*
|
* @param file : Fichier du validateur
|
* @param codeTypeFichier
|
* @return
|
* @throws Exception
|
*/
|
public static List<ColumnDefinition> retrieveFieldsFromValidator(File file, String codeTypeFichier) throws Exception {
|
|
Document doc = intialize(file);
|
|
NodeList entityList = doc.getElementsByTagName("entity"); //Liste des noeud <entity>
|
|
//Map qui stocke le champ à une position, ainsi que les caractéristiques de champ(typeDonnee, taille, index de debut d'extraction)
|
Map<Integer, Map<String, String>> mapParams = new HashMap<>();
|
|
int position = 1;
|
|
//Le validateur XML doit avoir au moins deux balises <entity> pour être conforme
|
if (entityList.getLength() >= 2) {
|
|
//Liste des noeud de type <validation> du deuxième Noeud <entity>
|
NodeList entityFileLineChildren = entityList.item(1).getChildNodes();
|
|
//Map qui contient champ set son nombe d'occurrence dans le fichier en cours de traitement
|
Map<String, Integer> mapFieldName = new HashMap<>();
|
|
//parcours de la balise <entity> pour récupérer ses enfants
|
for (int i = 0; i < entityFileLineChildren.getLength(); i++) {
|
|
if (entityFileLineChildren.item(i) != null && entityFileLineChildren.item(i).getAttributes() != null) {
|
|
//balise <validation>
|
Node validation = entityFileLineChildren.item(i);
|
|
if (validation != null) {
|
Map<String, String> mapAttributes = new HashMap<>();
|
|
//Liste des assertions de la balise <validation>
|
NodeList assertions = validation.getChildNodes();
|
|
for (int r = 0; r < assertions.getLength(); r++) {
|
|
Node assertion = assertions.item(r);
|
|
if (assertion != null && assertion.getAttributes() != null) {
|
NamedNodeMap assertionAttributes = assertion.getAttributes();
|
|
for (int q = 0; q < assertionAttributes.getLength(); q++) {
|
String assertionAttributeName = assertionAttributes.item(q).getNodeName();
|
String assertionAttributeValue = assertionAttributes.item(q).getNodeValue();
|
|
if (assertionAttributeName.equalsIgnoreCase(Constantes.ERROR_CODE)) {
|
String fieldName = constructFieldName(assertionAttributeValue, codeTypeFichier);
|
|
//Stocker le nbre d'occurrences trouvés dans la map
|
if (mapFieldName.containsKey(fieldName)) {
|
Integer nbOccurrences = mapFieldName.get(fieldName);
|
mapFieldName.replace(fieldName, nbOccurrences + 1);
|
|
} else {
|
mapFieldName.put(fieldName, 1);
|
}
|
Integer nbOccurrences = mapFieldName.get(fieldName);
|
String finalFieldName = nbOccurrences == 1 ? fieldName : fieldName + (nbOccurrences - 1);
|
|
mapAttributes.put(Constantes.FIELD_NAME, finalFieldName);
|
break;
|
}
|
}
|
//Liste des balises <param-value> de la balise <assertion>
|
NodeList params = assertion.getChildNodes();
|
|
for (int j = 0; j < params.getLength(); j++) {
|
|
if (params.item(j) != null && params.item(j).getAttributes() != null) {
|
|
//Les attributs de la balise <param-value>
|
NamedNodeMap attributesParamValue = params.item(j).getAttributes();
|
Integer positionAttribute = null;
|
|
for (int k = 0; k < attributesParamValue.getLength(); k++) {
|
|
String nodeValue = attributesParamValue.item(k).getNodeValue();
|
String nextNodeValue = attributesParamValue.item(++k).getNodeValue();
|
mapAttributes.put(nodeValue, nextNodeValue);
|
|
if (nodeValue.equals(Constantes.LIBELLE_TAILLE) && !nextNodeValue.equalsIgnoreCase(Constantes.EQUAL_PARAM)) {
|
mapAttributes.put(nodeValue, nextNodeValue);
|
|
} else if (nodeValue.equals(Constantes.LIBELLE_TYPE_DONNEE)) {
|
mapAttributes.put(nodeValue, nextNodeValue);
|
} else if (nodeValue.equals(Constantes.LIBELLE_POSITION)) {
|
positionAttribute = Integer.valueOf(nextNodeValue);
|
}
|
}
|
mapParams.put(positionAttribute != null ? positionAttribute : position, mapAttributes);
|
}
|
}
|
}
|
}
|
}
|
position++;
|
}
|
|
}
|
|
}
|
|
// mapParams.remove(mapParams.size());
|
List<ColumnDefinition> columnsDefinition = getColumnsDefinition(mapParams);
|
|
return columnsDefinition;
|
|
}
|
|
/**
|
* Méthode utilitaire pour extraire les données dans un fichier xml
|
*
|
* @param array
|
* @return
|
* @throws Exception
|
*/
|
private static Document intialize(File file) throws Exception {
|
|
/**
|
* Défini un factory qui aide à obtenir un parseur qui produit un arbre
|
* d'objets DOM à partir d'un document XML.
|
*/
|
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
|
/**
|
* création d'un objet du builder pour parser le fichier XML.
|
*/
|
DocumentBuilder db = dbf.newDocumentBuilder();
|
|
Document doc = db.parse(file);
|
|
doc.getDocumentElement().normalize();
|
|
return doc;
|
}
|
|
/**
|
* Méthode qui met les informations du validateur dans un ColumnDefinition
|
* pour utilisation future
|
*
|
* @param mapStructure
|
* @return
|
*/
|
private static List<ColumnDefinition> getColumnsDefinition(Map<Integer, Map<String, String>> mapStructure) throws ValidatorException {
|
List<ColumnDefinition> columns = new ArrayList<>();
|
|
for (Integer key : mapStructure.keySet()) {
|
ColumnDefinition column = new ColumnDefinition();
|
Map<String, String> value = mapStructure.get(key);
|
column.setPosition(key);
|
|
if (value.get(Constantes.LIBELLE_TAILLE) != null) {
|
column.setTaille(Integer.parseInt(value.get(Constantes.LIBELLE_TAILLE)));
|
}
|
column.setName(value.get(Constantes.FIELD_NAME));
|
column.setTypeDonnee(TypeDonnee.fromValeur(value.get(Constantes.LIBELLE_TYPE_DONNEE)).getValue());
|
|
if (column.getTypeDonnee().equalsIgnoreCase(TypeDonnee.DECIMAL.toString())) {
|
|
if (value.get(Constantes.LIBELLE_TAILLE_PARTIE_DECIMALE) != null) {
|
column.setTaillePartieDecimale(Integer.parseInt(value.get(Constantes.LIBELLE_TAILLE_PARTIE_DECIMALE)));
|
}
|
|
} else if (column.getTypeDonnee().equalsIgnoreCase(TypeDonnee.DATE.toString())) {
|
String separateurDate = value.get(Constantes.LIBELLE_SEPARATEUR_DATE);
|
String formatDate = value.get(Constantes.LIBELLE_FORMAT_DATE);
|
|
if (formatDate != null && !formatDate.isEmpty()) {
|
|
if (separateurDate != null && !separateurDate.isEmpty()) {
|
|
if (separateurDate.equals("-") || separateurDate.equals("/")) {
|
formatDate = addSeparateurToDateFormat(formatDate, separateurDate, column.getName());
|
|
} else {
|
throw new ValidatorException("Le séparateur de date du champ " + column.getName() + " ne peut être " + separateurDate);
|
}
|
}
|
column.setFormatDate(formatDate);
|
column.setSeparateurDate(separateurDate);
|
} else {
|
throw new ValidatorException("Le format date du champ " + column.getName() + " est absent");
|
}
|
}
|
|
columns.add(column);
|
}
|
|
return columns;
|
}
|
|
/**
|
* Méthode qui ajoute le séparateur renseigné dans le validateur au format
|
*
|
* @param formatDate
|
* @param separateurDate
|
* @param columnName
|
* @return
|
*/
|
public static String addSeparateurToDateFormat(String formatDate, String separateurDate, String columnName) {
|
StringBuilder dateValue = new StringBuilder();
|
|
switch (formatDate) {
|
case "ddMMyyyy":
|
dateValue.append("dd").append(separateurDate).append("MM").append(separateurDate).append("yyyy");
|
break;
|
case "ddyyyyMM":
|
dateValue.append("dd").append(separateurDate).append("yyyy").append(separateurDate).append("MM");
|
break;
|
case "MMddyyyy":
|
dateValue.append("MM").append(separateurDate).append("dd").append(separateurDate).append("yyyy");
|
break;
|
case "MMyyyydd":
|
dateValue.append("MM").append(separateurDate).append("yyyy").append(separateurDate).append("dd");
|
break;
|
case "yyyyddMM":
|
dateValue.append("yyyy").append(separateurDate).append("dd").append(separateurDate).append("MM");
|
break;
|
case "yyyyMMdd":
|
dateValue.append("yyyy").append(separateurDate).append("MM").append(separateurDate).append("dd");
|
break;
|
case "yyyy":
|
dateValue.append("yyyy");
|
break;
|
case "yyyyMM":
|
dateValue.append("yyyy").append(separateurDate).append("MM");
|
case "MMyyyy":
|
dateValue.append("MM").append(separateurDate).append("yyyy");
|
break;
|
default:
|
throw new ValidatorException("Le format date " + formatDate + " du champ" + columnName + " n'est pas acceptable ");
|
}
|
|
return dateValue.toString();
|
}
|
|
private static String constructFieldName(String fieldName, String codeTypeFichier) {
|
|
fieldName = fieldName.startsWith(codeTypeFichier)
|
? fieldName.substring(6)
|
: fieldName;
|
fieldName = fieldName.equalsIgnoreCase("int") ? "_" + fieldName : fieldName;
|
return removeAccents(fieldName.replaceAll(" ", "_"));
|
}
|
|
private static String removeAccents(String input) {
|
// Normalize to decomposed form (NFD): é → e + ´, è → e + `
|
String normalized = Normalizer.normalize(input, Normalizer.Form.NFD);
|
// Remove all diacritical marks (accents)
|
return normalized.replaceAll("\\p{M}", "");
|
}
|
}
|