From b3d0580439b9a00c7eb918085de1694151066004 Mon Sep 17 00:00:00 2001
From: Kenmegne <stephanie.kenmegne@gmail.com>
Date: Thu, 18 Jun 2026 16:02:49 +0000
Subject: [PATCH] rename packages
---
fdx_convert/src/main/java/com/megatim/fdxconvert/util/ImportData.java | 1138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1,138 insertions(+), 0 deletions(-)
diff --git a/fdx_convert/src/main/java/com/megatim/fdxconvert/util/ImportData.java b/fdx_convert/src/main/java/com/megatim/fdxconvert/util/ImportData.java
new file mode 100644
index 0000000..b928edd
--- /dev/null
+++ b/fdx_convert/src/main/java/com/megatim/fdxconvert/util/ImportData.java
@@ -0,0 +1,1138 @@
+/*
+ * 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.typefichier.validator.utilities.Constantes;
+import com.megatim.fdxconvert.pojo.DataToImport;
+import com.megatim.fdxconvert.pojo.FileToValidateDescription;
+import com.megatim.fdxconvert.exceptions.AttributeFormatException;
+import static com.megatim.typefichier.validator.utilities.Utilities.getCharset;
+import com.megatim.fdxconvert.model.AlphaNumeriqueField;
+import com.megatim.fdxconvert.model.TruncatedElement;
+import com.megatim.fdxconvert.model.Validateur;
+import com.megatim.fdxconvert.pojo.ResultFileParsing;
+import com.megatim.fdxconvert.service.ConfigurationService;
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.text.Normalizer;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.csv.CSVRecord;
+import org.apache.commons.text.StringEscapeUtils;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+/**
+ *
+ * @author mela
+ */
+public class ImportData {
+
+ /**
+ * Méthode qui parse le fichier csv et en extrait les données
+ *
+ * @param <T>
+ * @param datIm
+ * @return
+ * @throws java.lang.Exception
+ */
+ public static <T> List<T> importDataFromCsvFile(DataToImport<T> datIm) throws Exception {
+
+// FileReader reader = null;
+ List<String[]> datas = new ArrayList<>();
+
+ List<T> listeToReturn = new ArrayList<>();
+
+ if (datIm != null) {
+
+ try ( FileInputStream fis = new FileInputStream(datIm.getFile()); InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8); BufferedReader reader = new BufferedReader(isr)) {
+
+ String line = "";
+
+ while ((line = reader.readLine()) != null) {
+
+ String[] row = line.split(datIm.getRowDelimiter());
+
+ for (String r : row) {
+
+ String[] values = new String[datIm.getFields().size()];
+
+ String[] columns = r.split(datIm.getColumnDelimiter());
+
+ int ss = 0;
+
+ while (ss < datIm.getFields().size() && ss < columns.length) {
+
+ values[ss] = columns[ss];
+
+ ss++;
+ }
+
+ datas.add(values);
+
+ }
+
+ }
+
+ } catch (FileNotFoundException ex) {
+
+ Logger.getLogger(ImportData.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
+
+ } catch (IOException ex) {
+
+ Logger.getLogger(ImportData.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
+
+ }
+
+ if (!datas.isEmpty()) {
+
+ //tous les champs du type paramétré
+ Field[] fields = datIm.getType().getDeclaredFields();
+
+ // mettre les champs du type paramétré dans une map afin de faciliter leur accès
+ Map<String, Field> fieldsToMap = fieldsToMap(fields);
+
+ datas.forEach(d -> {
+
+ try {
+
+ T obj = datIm.getType().newInstance();
+
+ Map<String, String> map = tabToMap(datIm.getFields(), d);
+
+ for (Field field : fields) {
+
+ String fieldName = field.getName();
+
+ if (map.containsKey(fieldName) && fieldsToMap.containsKey(fieldName)) {
+
+ try {
+
+ Object converted = convertToPrimitive(field, map.get(fieldName));
+ Method method = new PropertyDescriptor(fieldName, datIm.getType()).getWriteMethod();
+ method.invoke(obj, converted);
+
+ } catch (IntrospectionException | IllegalAccessException | InvocationTargetException ex) {
+
+ Logger.getLogger(ImportData.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
+
+ } catch (IllegalArgumentException | ClassCastException ex) {
+
+ throw new AttributeFormatException("Erreur de type sur le champ " + fieldName);
+
+ }
+
+ }
+
+ }
+
+ listeToReturn.add(obj);
+
+ } catch (InstantiationException | IllegalAccessException ex) {
+
+ Logger.getLogger(ImportData.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
+
+ }
+
+ });
+
+ }
+
+ }
+
+ return listeToReturn;
+
+ }
+
+ /**
+ * Méthode qui extrait les données d'un fichier csv et les normalise
+ *
+ * @param rawCsvData : objet contenant les informations de validationdonnées
+ * @param validateur : Validateur du type fichier auquel appartient le
+ * fichier à valider
+ * @param outputFile : fichier texte généré en sortie
+ * @param headerPresent : renseigne si le fichier a une ligne d'entête
+ * @param alphaNumeriqueToBeTruncated : liste des champs à tronquer
+ * @throws Exception
+ */
+ public static void parseCsvFile(FileToValidateDescription rawCsvData, Validateur validateur, File outputFile, boolean headerPresent, Set<AlphaNumeriqueField> alphaNumeriqueToBeTruncated) throws Exception {
+
+ Map<Integer, Map> mapParams = ParserUtils.getValidateurElements(validateur);
+ AtomicInteger numeroLigne = new AtomicInteger(0);
+ AtomicBoolean columnTruncated = new AtomicBoolean();
+ int lineNumber = 1;
+
+ if (rawCsvData != null) {
+ Charset charset = getCharset(rawCsvData.getFile());
+
+ AtomicBoolean withHeader = new AtomicBoolean(headerPresent);
+ Path pathOfTruncatedElts = createTruncatedEltsPath(validateur, rawCsvData.getFile());
+
+ try ( FileInputStream fis = new FileInputStream(rawCsvData.getFile()); InputStreamReader isr = new InputStreamReader(fis, charset); BufferedReader reader = new BufferedReader(isr)) {
+ try ( BufferedWriter bufferWriter = Files.newBufferedWriter(outputFile.toPath(), charset, StandardOpenOption.APPEND, StandardOpenOption.CREATE, StandardOpenOption.SYNC); BufferedWriter truncateWriter = Files.newBufferedWriter(pathOfTruncatedElts, StandardCharsets.UTF_8, StandardOpenOption.APPEND, StandardOpenOption.CREATE, StandardOpenOption.SYNC)) {
+
+ CSVParser parser = new CSVParser(reader, CSVFormat.DEFAULT.builder()
+ .setSkipHeaderRecord(headerPresent)
+ .setIgnoreSurroundingSpaces(true)
+ .setTrim(true)
+ .setDelimiter(StringEscapeUtils.unescapeJava(rawCsvData.getColumnDelimiter()))
+ .setRecordSeparator(StringEscapeUtils.unescapeJava(rawCsvData.getRowDelimiter()))
+ .build());
+
+ for (CSVRecord record : parser) {
+
+ String[] columnsTableLine = new String[record.size()];
+ AtomicInteger i = new AtomicInteger(0);
+
+ if (!withHeader.get()) {
+
+ record.forEach(column -> {
+ columnsTableLine[i.get()] = column != null ? column.replaceAll(" {2,}", " ").replaceAll("\r", "").replaceAll("\n", "").replaceAll("\t", "").trim() : "";
+ i.set(i.get() + 1);
+ });
+
+ //Nettoyage d'une colonne de chaque ligne
+ ResultFileParsing resultFileParsing = buildFinalColumnsTableLine(outputFile, columnsTableLine, mapParams, alphaNumeriqueToBeTruncated, numeroLigne.incrementAndGet(), truncateWriter);
+ String[] finalColumnsTableLine = resultFileParsing.getFinalColumnsTableLine();
+ columnTruncated.set(resultFileParsing.isColumnTruncated());
+
+ String[] encodedStrings = ParserUtils.encodeStrings(finalColumnsTableLine, charset);
+ ParserUtils.writeToFile(encodedStrings, bufferWriter);
+
+ lineNumber++;
+ } else {
+ withHeader.set(false);
+ }
+
+ }
+
+ } catch (Exception e) {
+ Logger.getLogger(ImportData.class.getName()).log(Level.SEVERE, e.getMessage(), e);
+ }
+
+ //Si au moins une colonne a été tronqué, alors copier le fichier dont les lignes ont été tronqué dans le répertoire d'archivage
+ if (columnTruncated.get()) {
+ Path originalFilePathInArchiveFolder = createOriginalFileInArchive(validateur, rawCsvData.getFile());
+
+ //Copie du fichier dont les colonnes ont été tronqués vers le répertoire archivage
+ if (rawCsvData.getFile().exists()) {
+ Files.copy(rawCsvData.getFile().toPath(), originalFilePathInArchiveFolder);
+ }
+
+ } else {//Sinon supprimer le fichier des éléments tronqués, car il est vide
+ Files.deleteIfExists(pathOfTruncatedElts);
+ }
+ }
+ }
+ }
+
+ /**
+ * Méthode qui extrait les données dans un fichier txt en respectant
+ * scrupuleusement la taille de chaque colonne
+ *
+ * @param rawCsvData : objet contenant les informations de validationdonnées
+ * @param validateur : Validateur du type fichier auquel appartient le
+ * fichier à valider
+ * @param outputFile : fichier texte généré en sortie
+ * @param headerPresent : renseigne si le fichier a une ligne d'entête
+ * @throws Exception
+ */
+ public static void parseFileByFieldLength(FileToValidateDescription rawCsvData, Validateur validateur, File outputFile, boolean headerPresent) throws Exception {
+ System.out.println("----------------------In parseFileByFieldLength------------------");
+ Map<Integer, Map> mapParams = ParserUtils.getValidateurElements(validateur);
+ //boolean result = true;
+ int nbLine = 0;
+
+ if (rawCsvData != null) {
+
+ Charset charset = getCharset(rawCsvData.getFile());
+
+ //Lecture des lignes du fichier et chargment dans une liste
+ try ( FileInputStream fis = new FileInputStream(rawCsvData.getFile()); InputStreamReader isr = new InputStreamReader(fis, charset); BufferedReader reader = new BufferedReader(isr)) {
+
+ try ( //Initialisation du write pour traiter chaque ligne du fichier
+ BufferedWriter bufferWriter = Files.newBufferedWriter(outputFile.toPath(), charset, StandardOpenOption.APPEND, StandardOpenOption.CREATE, StandardOpenOption.SYNC);) {
+
+ boolean withHeader = headerPresent;
+
+ StringBuilder line = new StringBuilder();
+
+ int c = 0;
+
+ boolean carriageReaded = false; //Indique si on a lu un retour chariot
+
+ char lastCharacter = '\u0000';
+
+ while ((c = reader.read()) != -1) {
+
+ char characterRead = (char) c;
+
+ if (characterRead == '\r') {
+
+ if (carriageReaded) { //On a lu le retour chariot deux fois consécutives donc on a pas de séparateur de ligne au sens windows
+
+ //On ajoute les deux caractère à la chaîne que nous construisons
+ line.append('\r').append(characterRead);
+
+ carriageReaded = false; //On marque que la lecture d'une nouvelle ligne redémarre
+
+ } else { // Première lecture du retour chariot
+
+ carriageReaded = true; // On marque que nous avons lu un retour chariot
+
+ }
+
+ } else {
+
+ if (carriageReaded) { // Le caractère précédemment lu c'est le retour chariot
+
+ if (characterRead == '\n') { // Si le nouveau caractère lu est un saut de ligne c'est que nous venons de lire une nouvelle ligne
+
+ //On effectue les traitements propres à la ligne
+ String newLine = line.toString();
+ nbLine++;
+
+ if (!withHeader) {
+
+ parseLineUsingFieldLength(newLine, mapParams, rawCsvData.getColumnDelimiter(), bufferWriter, charset);
+
+ } else {
+
+ withHeader = false;
+
+ }
+
+ line = new StringBuilder(); //On réinitialise notre constructeur de ligne
+
+ carriageReaded = false; //On marque que la lecture d'une nouvelle ligne redémarre
+
+ } else {
+
+ line.append(' '); //On change le saut de ligne par un espace
+
+ }
+
+ } else {
+
+ if (characterRead == '\n') {
+
+ if (lastCharacter != '\n') {
+
+ line.append(' ');
+
+ }
+
+ } else {
+
+ line.append(characterRead);
+
+ }
+
+ }
+
+ }
+
+ lastCharacter = characterRead;
+ }
+
+ } //Fermeture du writer
+
+ }
+
+ }
+
+ }
+
+ /**
+ * Méthode qui parcours un fichier txt caractère par caractère afin d'en
+ * extraire les données et de les normaliser
+ *
+ * @param rawCsvData : objet contenant les informations de validationdonnées
+ * @param validateur : Validateur du type fichier auquel appartient le
+ * fichier à valider
+ * @param outputFile : fichier texte généré en sortie
+ * @param headerPresent : renseigne si le fichier a une ligne d'entête
+ * @param alphaNumeriqueToBeTruncated : liste des champs à tronquer
+ * @throws Exception
+ */
+ public static void parseFileCharacterByCharacter(FileToValidateDescription rawCsvData, Validateur validateur, File outputFile, boolean headerPresent, Set<AlphaNumeriqueField> alphaNumeriqueToBeTruncated) throws Exception {
+
+ Map<Integer, Map> mapParams = ParserUtils.getValidateurElements(validateur);
+ AtomicInteger numeroLigne = new AtomicInteger(0);
+ AtomicBoolean columnTruncated = new AtomicBoolean();
+
+ if (rawCsvData != null) {
+
+ Charset charset = getCharset(rawCsvData.getFile());
+ Path pathOfTruncatedElts = createTruncatedEltsPath(validateur, rawCsvData.getFile());
+
+ //Lecture des lignes du fichier et chargement dans une liste
+ try ( FileInputStream fis = new FileInputStream(rawCsvData.getFile()); InputStreamReader isr = new InputStreamReader(fis, charset); BufferedReader reader = new BufferedReader(isr)) {
+
+ try ( //Initialisation du write pour traiter chaque ligne du fichier
+ BufferedWriter bufferWriter = Files.newBufferedWriter(outputFile.toPath(), charset, StandardOpenOption.APPEND, StandardOpenOption.CREATE, StandardOpenOption.SYNC); BufferedWriter truncateWriter = Files.newBufferedWriter(pathOfTruncatedElts, StandardCharsets.UTF_8, StandardOpenOption.APPEND, StandardOpenOption.CREATE, StandardOpenOption.SYNC)) {
+
+ boolean withHeader = headerPresent;
+
+ StringBuilder line = new StringBuilder();
+
+ int c = 0;
+
+ boolean carriageReaded = false; //Indique si on a lu un retour chariot
+
+ char lastCharacter = '\u0000';
+
+ while ((c = reader.read()) != -1) {
+
+ char characterRead = (char) c;
+
+ if (characterRead == '\r') {
+
+ if (carriageReaded) { //On a lu le retour chariot deux fois consécutives donc on a pas de séparateur de ligne au sens windows
+
+ //On ajoute les deux caractère à la chaîne que nous construisons
+ line.append('\r').append(characterRead);
+
+ carriageReaded = false; //On marque que la lecture d'une nouvelle ligne redémarre
+
+ } else { // Première lecture du retour chariot
+
+ carriageReaded = true; // On marque que nous avons lu un retour chariot
+
+ }
+
+ } else {
+
+ if (carriageReaded) { // Le caractère précédemment lu c'est le retour chariot
+
+ if (characterRead == '\n') { // Si le nouveau caractère lu est un saut de ligne c'est que nous venons de lire une nouvelle ligne
+
+ //On effectue les traitements propres à la ligne
+ String newLine = line.toString();
+
+ if (ParserUtils.characterOfDelimiteur(rawCsvData.getColumnDelimiter()) != '\0') {
+ newLine = newLine.replaceAll(" {2,}", " ");
+ }
+
+ if (!withHeader) {
+
+ //Représente les colonnes extraites de chaque ligne du fichier
+ //String[] columnsTableLine = newLine.split(rawCsvData.getColumnDelimiter());
+ String[] columnsTableLine;
+
+ if (rawCsvData.getColumnDelimiter().equals("\\t")) {
+
+ columnsTableLine = ParserUtils.splitIntoColumns(newLine, '\t');
+ ResultFileParsing resultFileParsing = buildFinalColumnsTableLine(outputFile, columnsTableLine, mapParams, alphaNumeriqueToBeTruncated, numeroLigne.incrementAndGet(), truncateWriter);
+ String[] finalColumnsTableLine = resultFileParsing.getFinalColumnsTableLine();
+ columnTruncated.set(resultFileParsing.isColumnTruncated());
+
+ String[] encodedStrings = ParserUtils.encodeStrings(finalColumnsTableLine, charset);
+ ParserUtils.writeToFile(encodedStrings, bufferWriter);
+
+ } else if (rawCsvData.getColumnDelimiter().isEmpty()) {
+ parseLineUsingFieldLength(newLine, mapParams, rawCsvData.getColumnDelimiter(), bufferWriter, charset);
+ } else {
+
+ columnsTableLine = (newLine).split(rawCsvData.getColumnDelimiter());
+ ResultFileParsing resultFileParsing = buildFinalColumnsTableLine(outputFile, columnsTableLine, mapParams, alphaNumeriqueToBeTruncated, numeroLigne.incrementAndGet(), truncateWriter);
+ String[] finalColumnsTableLine = resultFileParsing.getFinalColumnsTableLine();
+
+ if (!columnTruncated.get()) {
+ columnTruncated.set(resultFileParsing.isColumnTruncated());
+ }
+
+ String[] encodedStrings = ParserUtils.encodeStrings(finalColumnsTableLine, charset);
+ ParserUtils.writeToFile(encodedStrings, bufferWriter);
+
+ }
+
+ //Nettoyage d'une colonne de chaque ligne
+ } else {
+
+ withHeader = false;
+
+ }
+
+ line = new StringBuilder(); //On réinitialise notre constructeur de ligne
+
+ carriageReaded = false; //On marque que la lecture d'une nouvelle ligne redémarre
+
+ } else {
+
+ line.append(' '); //On change le saut de ligne par un espace
+
+ }
+
+ } else {
+
+ if (characterRead == '\n') {
+
+ if (lastCharacter != '\n') {
+
+ line.append(' ');
+
+ }
+
+ } else {
+
+ line.append(characterRead);
+
+ }
+
+ }
+
+ }
+
+ lastCharacter = characterRead;
+ }
+
+ } //Fermeture du writer
+
+ }
+
+ //Si au moins une colonne a été tronqué, alors copier le fichier dont les lignes ont été tronqué dans le répertoire d'archivage
+ if (columnTruncated.get()) {
+ Path originalFilePathInArchiveFolder = createOriginalFileInArchive(validateur, rawCsvData.getFile());
+
+ //Copie du fichier dont les colonnes ont été tronqués vers le répertoire archivage
+ if (rawCsvData.getFile().exists()) {
+ Files.copy(rawCsvData.getFile().toPath(), originalFilePathInArchiveFolder);
+ }
+
+ } else {//Sinon supprimer le fichier des éléments tronqués, car il est vide
+ Files.deleteIfExists(pathOfTruncatedElts);
+ }
+ }
+
+ }
+
+ /**
+ * Méthode qui extrait les données d'un fichier xlsx et les normalise
+ *
+ * @param validateur : Validateur du type fichier auquel appartient le
+ * fichier à valider
+ * @param outputFile : fichier texte généré en sortie
+ * @param headerPresent : renseigne si le fichier a une ligne d'entête
+ * @param alphaNumeriqueToBeTruncated : liste des champs à tronquer
+ * @param filePath : Fichier qui contient les données à extraire
+ * @throws IOException
+ * @throws Exception
+ */
+ public static void parseXlsxFile(String filePath, boolean headerPresent, File outputFile, Validateur validateur, Set<AlphaNumeriqueField> alphaNumeriqueToBeTruncated) throws Exception {
+ AtomicBoolean columnTruncated = new AtomicBoolean();
+ Path pathOfTruncatedElts = createTruncatedEltsPath(validateur, new File(filePath));
+
+ try ( InputStream is = new FileInputStream(filePath); Workbook wb = new XSSFWorkbook(is)) {
+ parseExcelFile(filePath, wb, headerPresent, outputFile, validateur, alphaNumeriqueToBeTruncated, pathOfTruncatedElts);
+ }
+ treatTruncatedElements(filePath, pathOfTruncatedElts, validateur, columnTruncated);
+
+ }
+
+ public static void parseXlsFile(String filePath, boolean headerPresent, File outputFile, Validateur validateur, Set<AlphaNumeriqueField> alphaNumeriqueToBeTruncated) throws Exception {
+ AtomicBoolean columnTruncated = new AtomicBoolean();
+ Path pathOfTruncatedElts = createTruncatedEltsPath(validateur, new File(filePath));
+
+ try ( InputStream is = new FileInputStream(filePath); Workbook wb = new HSSFWorkbook(is)) {
+ parseExcelFile(filePath, wb, headerPresent, outputFile, validateur, alphaNumeriqueToBeTruncated, pathOfTruncatedElts);
+ }
+ treatTruncatedElements(filePath, pathOfTruncatedElts, validateur, columnTruncated);
+
+ }
+
+ private static void parseExcelFile(String filePath, Workbook wb, boolean headerPresent, File outputFile, Validateur validateur, Set<AlphaNumeriqueField> alphaNumeriqueToBeTruncated, Path pathOfTruncatedElts) throws IOException, Exception {
+ Map<Integer, Map> mapParams = ParserUtils.getValidateurElements(validateur);
+ final int maxPosition = Collections.max(mapParams.keySet());
+ AtomicInteger numeroLigne = new AtomicInteger(0);
+ AtomicBoolean columnTruncated = new AtomicBoolean();
+ Charset charset = getCharset(new File(filePath));
+
+ try ( BufferedWriter bufferWriter = Files.newBufferedWriter(outputFile.toPath(), charset, StandardOpenOption.APPEND, StandardOpenOption.CREATE, StandardOpenOption.SYNC); BufferedWriter truncateWriter = Files.newBufferedWriter(pathOfTruncatedElts, Charset.defaultCharset(), StandardOpenOption.APPEND, StandardOpenOption.CREATE, StandardOpenOption.SYNC)) {
+
+ for (int i = 0; i < wb.getNumberOfSheets(); i++) {
+ Sheet sheet = wb.getSheetAt(i);
+ AtomicInteger numberOfColumns = new AtomicInteger(0);
+ AtomicBoolean withHeader = new AtomicBoolean(headerPresent);
+ AtomicInteger lineNumber = new AtomicInteger(1);
+
+ for (org.apache.poi.ss.usermodel.Row r : sheet) {
+
+ if (!withHeader.get()) {
+ for (int cn = 0; cn < r.getLastCellNum(); cn++) {
+ numberOfColumns.incrementAndGet();
+ }
+ //Représente les colonnes extraites de chaque ligne du fichier
+ String[] columnsTableLine = new String[numberOfColumns.get()];
+ AtomicInteger index = new AtomicInteger(0);
+
+ for (int cn = 0; cn < r.getLastCellNum(); cn++) {
+ if (cn < maxPosition) {
+ Map<String, String> map = mapParams.get(index.get() + 1);
+
+ //Prendre aussi les cellules vides en considération
+ org.apache.poi.ss.usermodel.Cell c = r.getCell(cn, org.apache.poi.ss.usermodel.Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
+ String value = com.megatim.typefichier.validator.utilities.ParserUtils.getXlxsCellValue(c,
+ wb,
+ map.get(Constantes.LIBELLE_TYPE_DONNEE),
+ map.get(Constantes.LIBELLE_FORMAT_DATE),
+ map.get(Constantes.LIBELLE_SEPARATEUR_DATE),
+ map.get(Constantes.ERROR_CODE));
+ columnsTableLine[index.get()] = value;
+ index.incrementAndGet();
+ } else {
+ break;
+ }
+ }
+
+ try {
+ //Nettoyage d'une colonne de chaque ligne
+ ResultFileParsing resultFileParsing = buildFinalColumnsTableLine(outputFile, columnsTableLine, mapParams, alphaNumeriqueToBeTruncated, numeroLigne.incrementAndGet(), truncateWriter);
+ String[] finalColumnsTableLine = resultFileParsing.getFinalColumnsTableLine();
+ columnTruncated.set(resultFileParsing.isColumnTruncated());
+
+ ParserUtils.writeToFile(finalColumnsTableLine, bufferWriter);
+
+ } catch (Exception ex) {
+ Logger.getLogger(ImportData.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
+ }
+ } else {
+ withHeader.set(false);
+ }
+ lineNumber.incrementAndGet();
+ }
+ }
+
+ }
+ }
+
+ private static void treatTruncatedElements(String filePath, Path pathOfTruncatedElts, Validateur validateur, AtomicBoolean columnTruncated) throws IOException {
+ //Si au moins une colonne a été tronqué, alors copier le fichier dont les lignes ont été tronqué dans le répertoire d'archivage
+ if (columnTruncated.get()) {
+ Path pathoriginalFilePath = Paths.get(filePath);
+ Path originalFilePathInArchiveFolder = createOriginalFileInArchive(validateur, new File(filePath));
+
+ //Copie du fichier dont les colonnes ont été tronqués vers le répertoire archivage
+ if (Files.exists(pathoriginalFilePath, LinkOption.NOFOLLOW_LINKS)) {
+ Files.copy(pathoriginalFilePath, originalFilePathInArchiveFolder);
+ }
+
+ } else {//Sinon supprimer le fichier des éléments tronqués, car il est vide
+ Files.deleteIfExists(pathOfTruncatedElts);
+ }
+ }
+
+ /**
+ * Méthode qui met les libellés des colonnes et leurs valeurs
+ * correspondantes dans une map
+ *
+ * @param titles : ensemble des noms de colonnes
+ * @param values : ensemble des données
+ * @return : rentourne une map (clé,valeur) = (nom_de_la_colonne,
+ * valeur_colonne)
+ */
+ private static Map<String, String> tabToMap(List<String> titles, String[] values) {
+ Map<String, String> map = new HashMap<>();
+ for (int i = 0; i < titles.size(); i++) {
+ map.put(titles.get(i), values[i]);
+ }
+
+ return map;
+ }
+
+ /**
+ * Méthode qui met un tableau de Field dans une
+ * map<nom_du_champ,objet représentant_le_champ>
+ * afin de faciliter leur accès
+ *
+ * @param fields
+ * @return
+ */
+ private static Map<String, Field> fieldsToMap(Field[] fields) {
+ Map<String, Field> map = new HashMap<>();
+ for (Field f : fields) {
+ map.put(f.getName(), f);
+ }
+
+ return map;
+ }
+
+ /**
+ * Méthode qui fait la conversion de la donnée extraite vers un type
+ * primitif
+ *
+ * @param field : objet contenant les informations sur le type auquel
+ * appartient le champ de la donnée extraite
+ * @param value : donnée à convertir
+ * @return : retourne un String si le type du champ ne figure pas dans la
+ * liste ci-dessus
+ */
+ private static Object convertToPrimitive(Field field, String value) {
+ Object obj = value;
+
+ if (field.getType().isAssignableFrom(Integer.class)
+ || field.getType().isAssignableFrom(int.class)) {
+ obj = Integer.valueOf(value);
+ } else if (field.getType().isAssignableFrom(Double.class)
+ || field.getType().isAssignableFrom(double.class)) {
+ obj = Double.valueOf(value);
+ } else if (field.getType().isAssignableFrom(java.math.BigDecimal.class)) {
+ obj = new java.math.BigDecimal(value);
+ } else if (field.getType().isAssignableFrom(Float.class)
+ || field.getType().isAssignableFrom(float.class)) {
+ obj = Float.valueOf(value);
+ } else if (field.getType().isAssignableFrom(Long.class)
+ || field.getType().isAssignableFrom(long.class)) {
+ obj = Long.valueOf(value);
+ } else if (field.getType().isAssignableFrom(Boolean.class)
+ || field.getType().isAssignableFrom(boolean.class)) {
+ Boolean.valueOf(value);
+ }
+
+ return obj;
+ }
+
+ /**
+ * Méthode permettant de construire la donnée finale à écrire dans le
+ * fichier texte
+ *
+ * @param outputFile
+ * @param initialColumnsTableLine
+ * @param mapParams
+ * @param fieldsToBeTruncated
+ * @param numeroLigne
+ * @param truncateWriter
+ * @return
+ * @throws Exception
+ */
+ private static ResultFileParsing buildFinalColumnsTableLine(File outputFile, String[] initialColumnsTableLine, Map<Integer, Map> mapParams, Set<AlphaNumeriqueField> fieldsToBeTruncated, int numeroLigne, BufferedWriter truncateWriter) throws Exception {
+
+ String[] finalColumnsTableLine = new String[mapParams.size() - 1];
+ String[] columnsTableLine = new String[mapParams.size() - 1];
+
+ //On copie les éléments à normaliser dans un nouveau tableau
+ for (int j = 0; j < finalColumnsTableLine.length; j++) {
+
+ //Arreter la copie si on atteint la fin du tableau initial
+ if (j == initialColumnsTableLine.length) {
+ j = finalColumnsTableLine.length;
+ } else {
+ final String result = initialColumnsTableLine[j] != null && !initialColumnsTableLine[j].isEmpty()
+ ? Normalizer
+ .normalize(initialColumnsTableLine[j], Normalizer.Form.NFD) //Retrait des caractères accentués
+ .replaceAll("\\p{M}+", "")
+ : "";
+ columnsTableLine[j] = result;
+ }
+ }
+
+ //Type de données utilisé pour retourner le résultat de la construction des lignes de données
+ ResultFileParsing resultFileParsing = new ResultFileParsing();
+
+ int index = 0;
+
+ for (String str : columnsTableLine) {
+
+ String columnTableLine = str != null ? str.trim() : "";
+
+ if (index < mapParams.size() - 1) {
+
+ Map<String, String> map = mapParams.get(index + 1);
+
+ final int taille = Integer.parseInt(map.get(Constantes.LIBELLE_TAILLE));
+ String typeDonnee = map.get(Constantes.LIBELLE_TYPE_DONNEE);
+
+ //Traitement d'une donnée de type décimal
+ if (typeDonnee.equalsIgnoreCase(Constantes.LIBELLE_DECIMAL)) {
+ finalColumnsTableLine[index] = normalizeDecimal(columnTableLine, map);
+
+ //Traitement d'une donnée de type DATE
+ } else if (typeDonnee.equalsIgnoreCase(Constantes.LIBELLE_DATE)) {
+
+ if (columnTableLine.length() < taille) {
+ finalColumnsTableLine[index] = generateUnknown(taille - columnTableLine.length(), " ") + columnTableLine;
+
+ } else if (columnTableLine.length() == taille) {
+ finalColumnsTableLine[index] = columnTableLine;
+
+ } else {
+ finalColumnsTableLine[index] = columnTableLine.substring(0, taille);
+ }
+
+ //Traitement d'une donnée de type NUMERIQUE
+ } else if (typeDonnee.equalsIgnoreCase(Constantes.LIBELLE_NUMERIQUE)) {
+ finalColumnsTableLine[index] = normalizeNumber(columnTableLine, taille);
+//
+ } else if (typeDonnee.equalsIgnoreCase(Constantes.LIBELLE_ALPHANUMERIQUE)) { //Traitement d'une donnée de type ALPHANUMERIQUE
+
+ if (columnTableLine.length() < taille) {
+
+ finalColumnsTableLine[index] = generateUnknown(taille - columnTableLine.length(), " ") + columnTableLine;
+
+ } else if (columnTableLine.length() == taille) {
+
+ finalColumnsTableLine[index] = columnTableLine;
+
+ } else {
+
+ if (!fieldsToBeTruncated.isEmpty()) {
+
+ //Récupérer l'index de début du champ en cours de traitement
+ int indexDebutChamp = Integer.parseInt(map.get(Constantes.LIBELLE_INDEX));
+
+ //Mettre les champs à tronquer dans une liste afin d'y rechercher le champ en cours de traitement
+ List<AlphaNumeriqueField> liste = Arrays.asList(fieldsToBeTruncated.toArray(new AlphaNumeriqueField[0]))
+ .stream().filter(a -> {
+
+ // ici on vérifie si l'index de début du champ en cours de traitement correspond à l'index d'un des champs à tronquer
+ //Car si 2 champs ont le même index, alors il s'agit d'un seul champ
+ return a.getIndex() == indexDebutChamp;
+ }).collect(Collectors.toList());
+
+ // Si on a trouvé un champ à tronquer qui a le même index que le champ courant alors, tronquer le champ
+ boolean found = (liste.size() == 1);
+
+ if (found) {
+
+ AlphaNumeriqueField alphaField = liste.get(0);
+
+ String finalData = columnTableLine.substring(0, taille);
+
+ TruncatedElement truncatedElement = new TruncatedElement(alphaField.getValidateur().getCodeTypeFichier(),
+ alphaField.getCodeColonne(), columnTableLine, finalData,
+ outputFile.getName(), LocalDateTime.now(), numeroLigne, taille, columnTableLine.length());
+
+// Journalisation du champs tronqués
+ writeTruncatedElementsToFile(truncatedElement, truncateWriter);
+
+ resultFileParsing.setColumnTruncated(true);
+
+ finalColumnsTableLine[index] = finalData;
+ } else {
+ finalColumnsTableLine[index] = columnTableLine;
+ }
+
+ } else {
+ finalColumnsTableLine[index] = columnTableLine;
+ }
+ }
+ } else {
+ finalColumnsTableLine[index] = columnTableLine;
+ }
+ }
+
+ index++;
+
+ }
+
+ resultFileParsing.setFinalColumnsTableLine(finalColumnsTableLine);
+ return resultFileParsing;
+ }
+
+ /**
+ * Méthode qui normalise un nombre en ajoutant des zéros à gauche
+ *
+ * @param value
+ * @param taille
+ * @return
+ */
+ private static String normalizeNumber(String value, int taille) {
+ String newValue = value
+ .trim()
+ .replaceAll("\\s+", "")
+ .replaceAll("\\u00A0", "")//nbsp
+ .replaceAll(" ", "")//nbsp
+ .replaceAll("\\p{Z}", "")
+ .replaceAll("\t", "")
+ .replaceAll("\r", "")
+ .replaceAll("\n", "");
+
+ try {
+ if (!newValue.matches("\\d+")) {
+ newValue = new BigDecimal(newValue.replace(',', '.')).longValue() + "";//Remplacer la virgule par le point
+ }
+ } catch (Exception ex) {
+ }
+ return generateUnknown(taille - newValue.length(), " ") + newValue;
+ }
+
+ /**
+ * Méthode qui normalise les nombres décimaux conformat aux tailles, en
+ * ajoutant éventuellement des zéros à gauche de la partie entière et à
+ * droite de la partie décimale renseignés dans le validateur
+ *
+ * @param value : chaîne à normaliser
+ * @param map : map contenant les infos sur les parties entire et décimale
+ * @return
+ */
+ private static String normalizeDecimal(String value, Map<String, String> map) {
+
+ //Taille totale du nombre décimal
+ int taille = Integer.parseInt(map.get(Constantes.LIBELLE_TAILLE));
+ int taillePartieDecimale = Integer.parseInt(map.get(Constantes.LIBELLE_TAILLE_PARTIE_DECIMALE));
+ String separateurDecimal = map.get(Constantes.LIBELLE_SEPARATEUR_DECIMAL);
+ int tailleReelle = taille + taillePartieDecimale + separateurDecimal.trim().length();
+
+ String newValue = value.trim()
+ .replaceAll("\\s+", "")
+ .replaceAll("\\u00A0", "")//nbsp
+ .replaceAll(" ", "")//nbsp
+ .replaceAll("\\p{Z}", "")
+ .replaceAll("\t", "")
+ .replaceAll("\r", "")
+ .replaceAll("\n", "");
+
+ if (newValue.length() >= tailleReelle) {
+ return newValue;
+ }
+ if (newValue.matches("^\\d+[,.]?\\d+$")
+ || newValue.matches("[-+]?\\d+(\\.\\d+)?[eE][-+]?\\d+")
+ || newValue.matches("^\\d{1,3},\\d+E[+-]?\\d+$")) {//Notation scientifique
+ try {
+ newValue = new BigDecimal(newValue.replace(',', '.')).toPlainString();//Remplacer la virgule par le point
+ } catch (Exception ex) {
+ }
+ }
+ return generateUnknown(tailleReelle - newValue.length(), " ") + newValue;
+ }
+
+ /**
+ * Méthode qui génère un nombre précis d'un quelconque caractère
+ *
+ * @param nbOfCharacter : nombre de fois à générer le caractère
+ * @param character : caractère à générer
+ * @return
+ */
+ private static String generateUnknown(int nbOfCharacter, String character) {
+ String str = "";
+
+ for (int i = 0; i < nbOfCharacter; i++) {
+ str += character;
+ }
+ return str;
+ }
+
+ /**
+ * Méthode qui extrait les données en se basant sur la taille des champs
+ * définis dans le validateur
+ */
+ private static void parseLineUsingFieldLength(String line, Map<Integer, Map> mapParams, String delimiteurColonne, BufferedWriter bufferWriter, Charset charset) throws IOException {
+
+ String[] columnsTableLine = new String[mapParams.size() - 1];
+
+ try {
+ int index = 0;
+ int i = 1;
+
+ while (i < mapParams.size()) {
+ Map<String, String> map = mapParams.get(i);
+
+ int taille = Integer.parseInt(map.get(Constantes.LIBELLE_TAILLE));
+
+ if (i == mapParams.size() - 1) {
+ columnsTableLine[i - 1] = line.substring(index);
+ } else {
+ columnsTableLine[i - 1] = line.substring(index, index + taille);
+ }
+
+ index = index + taille;
+
+ //recupérer le charactère correspondant au delimiteur
+ char character = ParserUtils.characterOfDelimiteur(delimiteurColonne);
+
+ //Si le démimiteur n'est pas la chaîne vide
+ if (character != '\0') {
+
+ //Si on ne trouve pas le délimiteur après avoir lu le champ précédent, on arrete le traitement de cette ligne car fichier mal formaté
+ if ((i < mapParams.size() - 1) && (line.charAt(index) != character)) {
+
+ //Interrompre l'extraction des données en remplissant la condition de sortie de laboucle
+ i = mapParams.size();
+ } else {
+
+ //Incrementer l'index un afin de traverser le séparateur
+ index = index + 1;
+ }
+
+ }
+ i++;
+ }
+
+ String[] encodedStrings = ParserUtils.encodeStrings(columnsTableLine, charset);
+ ParserUtils.writeToFile(encodedStrings, bufferWriter);
+
+ } catch (Exception ex) {
+ Logger.getLogger(ImportData.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
+ }
+
+ }
+
+ /**
+ * Méthode qui écrit les informations sur les éléments tronqués dans un
+ * fichier
+ *
+ * @param t
+ * @param bufferWriter
+ * @throws IOException
+ */
+ private static void writeTruncatedElementsToFile(TruncatedElement t, final BufferedWriter bufferWriter) throws IOException {
+
+ //Ecriture dans le fichier output
+ StringBuilder safeLineBuilder = new StringBuilder(0);
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+ LocalDateTime date = t.getDateAction();
+
+ safeLineBuilder.append("Fichier:").append(t.getFileName()).append("|");
+ safeLineBuilder.append("Date:").append(date.format(formatter)).append("|");
+ safeLineBuilder.append("Ligne:").append(t.getLineNumber()).append("|");
+ safeLineBuilder.append("Colonne:").append(t.getCodeColonne()).append("|");
+ safeLineBuilder.append("Taille attendue:").append(t.getTailleAttendue()).append("|");
+ safeLineBuilder.append("Donnée finale:").append(t.getFinalData()).append("|");
+ safeLineBuilder.append("Taille trouvée:").append(t.getTailleTrouvee()).append("|");
+ safeLineBuilder.append("Donnée initiale:").append(t.getInitialData());
+
+ String safeLine = safeLineBuilder.toString();
+
+ if (safeLine.length() > 0) {
+
+ bufferWriter.write(safeLine + System.lineSeparator());
+
+ }
+ }
+
+ /**
+ * Méthode qui retourne le nom fichier sans extension
+ *
+ * @param file
+ * @return
+ */
+ private static String fileNameWithoutExtension(File file) {
+ int index = file.getName().lastIndexOf(".");
+
+ if (index > 0) {
+
+ return file.getName().substring(0, index);
+ } else {
+ return file.getName();
+ }
+ }
+
+ /**
+ * Méthode qui construit le chemin du fichier qui va contenit les logs des
+ * éléments tronqués
+ *
+ * @param validateur
+ * @param outputFile
+ * @return
+ * @throws IOException
+ */
+ private static Path createTruncatedEltsPath(Validateur validateur, File outputFile) throws IOException {
+ final String arhivageDirectory = ConfigurationService.getInstance().getCurrentConfig().getArchivesDir();
+ final String today = LocalDate.now().toString();
+
+ Path logDir = Paths.get(arhivageDirectory, today, validateur.getCodeTypeFichier(), "logs");
+
+ if (!Files.exists(logDir, LinkOption.NOFOLLOW_LINKS)) {
+ Files.createDirectories(logDir);
+ }
+
+ Path pathOfTruncatedElts = Paths.get(arhivageDirectory, today, validateur.getCodeTypeFichier(), "logs", fileNameWithoutExtension(outputFile) + "_truncated_elements.txt");
+
+ return pathOfTruncatedElts;
+
+ }
+
+ /**
+ * méthode permettant de construire le chemin du fichier d'origine dans le
+ * répertoire d'archivages
+ *
+ * @param validateur
+ * @param originalFile
+ * @return
+ * @throws IOException
+ */
+ private static Path createOriginalFileInArchive(Validateur validateur, File originalFile) throws IOException {
+ final String arhivageDirectory = ConfigurationService.getInstance().getCurrentConfig().getArchivesDir();
+ final String today = LocalDate.now().toString();
+
+ Path originalFilesDir = Paths.get(arhivageDirectory, today, validateur.getCodeTypeFichier(), "fichiers");
+
+ if (!Files.exists(originalFilesDir, LinkOption.NOFOLLOW_LINKS)) {
+ Files.createDirectories(originalFilesDir);
+ }
+
+ Path originalFilePath = Paths.get(arhivageDirectory, today, validateur.getCodeTypeFichier(), "fichiers", originalFile.getName());
+ final String fileNameWithoutExtension = fileNameWithoutExtension(originalFile);
+
+ //Si le fichier existe dans le répertoire d'archivages, alors ajouter un numero d'ordre dans son nom
+ if (Files.exists(originalFilePath, LinkOption.NOFOLLOW_LINKS)) {
+ List<Path> existingFiles = Files.list(originalFilesDir).filter(p
+ -> p.toString().contains(fileNameWithoutExtension)).collect(Collectors.toList());
+
+ int nbFiles = existingFiles.size();
+
+ if (nbFiles > 0) {
+ originalFilePath = Paths.get(arhivageDirectory, today, validateur.getCodeTypeFichier(), "fichiers",
+ fileNameWithoutExtension + "(" + nbFiles + ")" + getFileExtension(originalFile));
+ }
+ }
+
+ return originalFilePath;
+ }
+
+ /**
+ * Méthode qui retourne l'extension d'un fichier
+ *
+ * @param file
+ * @return
+ */
+ private static String getFileExtension(File file) {
+ int index = file.getName().lastIndexOf(".");
+
+ if (index <= 0) {
+ return "";
+
+ } else {
+ return file.getName().substring(index);
+ }
+ }
+
+}
--
Gitblit v1.10.0