package com.megatim.fdxconvert.controller; import com.megatim.typefichier.validator.Validator; import com.megatim.typefichier.validator.model.ConfigJsonValidator; import com.megatim.typefichier.validator.model.ConfigStreamValidator; import com.megatimfx.common.abstracts.AbstractEditDialogController; import com.megatimfx.common.enums.TypeOperation; import com.megatimfx.common.utils.ViewLoaderUtil; import com.megatimfx.components.customdialogs.AlertMessageUtil; import com.megatimfx.components.customdialogs.LoadinIndicatorDialogUtil; import com.megatimfx.components.dialogs.NotificationDialog; import com.megatimfx.components.dialogs.NotificationType; import com.megatim.fdxconvert.dao.TypeFichierJsonDAO; import com.megatim.fdxconvert.dao.ValidateurDAO; import com.megatim.fdxconvert.enums.DataType; import com.megatim.fdxconvert.exceptions.ConfigException; import com.megatim.fdxconvert.exceptions.ValidatorException; import com.megatim.fdxconvert.forms.MetaAlphaNumeriqueFieldEditFormController; import com.megatim.fdxconvert.forms.FileToValidateEditFormController; import com.megatim.fdxconvert.model.AlphaNumeriqueField; import com.megatim.fdxconvert.model.Configuration; import com.megatim.fdxconvert.model.TypeFichierJson; import com.megatim.fdxconvert.pojo.FileToValidate; import com.megatim.fdxconvert.model.Validateur; import com.megatim.fdxconvert.service.ConfigurationService; import com.megatim.fdxconvert.util.ImportData; import com.megatim.fdxconvert.pojo.FileToValidateDescription; import com.megatim.fdxconvert.util.TypeFichierJsonConverter; import com.megatim.fdxconvert.util.Utilities; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URL; import java.nio.file.Paths; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.HashSet; import java.util.Optional; import java.util.Random; import java.util.ResourceBundle; import java.util.Set; import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.scene.Node; import javafx.scene.layout.Pane; import javafx.stage.Stage; import org.apache.commons.io.IOUtils; /** * * @author STEPHANIE */ public class FileToValidateEditDialogController extends AbstractEditDialogController { org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(FileToValidateEditDialogController.class); private FileToValidateEditFormController fileToValidateEditFormController; private MetaAlphaNumeriqueFieldEditDialogController metaAlphaNumeriqueFieldEditDialogController; @Override public String getTitle() { getEditButton().setText("Valider"); return "Conversion manuelle des fichiers"; } @Override public Pane getContentFormPane() throws IOException { return ViewLoaderUtil.getPaneFromFxmlFile(fileToValidateEditFormController.getClass().getResource("FileToValidateEditForm.fxml"), fileToValidateEditFormController); } @Override public Object getContentFormController() { return fileToValidateEditFormController; } @Override public void initialize(URL url, ResourceBundle rb) { fileToValidateEditFormController = new FileToValidateEditFormController(); metaAlphaNumeriqueFieldEditDialogController = new MetaAlphaNumeriqueFieldEditDialogController(); metaAlphaNumeriqueFieldEditDialogController.setAlphaNumeriqueFieldEditFormController(new MetaAlphaNumeriqueFieldEditFormController()); super.initialize(url, rb); } @Override protected void afterBindCurrentObjectWithFormField(FileToValidate bindObject, Object formController, TypeOperation typeOperation) { FileToValidateEditFormController controller = (FileToValidateEditFormController) formController; controller.getMetaAlphaNumeriqueFieldAbstractTable().setController(metaAlphaNumeriqueFieldEditDialogController); } @Override protected void afterBindFormFieldWithCurrentObject(FileToValidate bindObject, Object formController, TypeOperation typeOperation) { if (formController instanceof FileToValidateEditFormController) { FileToValidateEditFormController controller = (FileToValidateEditFormController) formController; controller.getMetaAlphaNumeriqueFieldAbstractTable().setController(metaAlphaNumeriqueFieldEditDialogController); switch (typeOperation) { case ADD: controller.getTypeFichierAbstractSelectItem().selectedElementProperty().addListener((observable, oldValue, newValue) -> { if (newValue != null) { metaAlphaNumeriqueFieldEditDialogController.getAlphaNumeriqueFieldEditFormController().setTypeFichier(newValue); if (controller.getDataTypeComboBox().getSelectionModel().getSelectedItem() != null && controller.getDataTypeComboBox().getSelectionModel().getSelectedItem().equals(DataType.JSON)) { controller.getSaisieAlphaNumeriqueFieldChecBox().setDisable(true); } controller.getSaisieAlphaNumeriqueFieldChecBox().setDisable(false); } }); fileToValidateEditFormController.getSaisieAlphaNumeriqueFieldChecBox().selectedProperty().addListener(listener -> { if (fileToValidateEditFormController.getSaisieAlphaNumeriqueFieldChecBox().isSelected()) { fileToValidateEditFormController.getMetaAlphaNumeriqueFieldAbstractTable().setDisable(false); } }); fileToValidateEditFormController.getStrictValidationCheckbox().selectedProperty().addListener(l -> { if (fileToValidateEditFormController.getStrictValidationCheckbox().isSelected()) { fileToValidateEditFormController.getMetaAlphaNumeriqueFieldAbstractTable().setDisable(true); } }); break; default: controller.getSaisieAlphaNumeriqueFieldChecBox().setSelected(true); controller.getSaisieAlphaNumeriqueFieldChecBox().setDisable(true); break; } } } @Override public void afterSave(ActionEvent event) { Configuration config = ConfigurationService.getInstance().getCurrentConfig(); if (getCurrentObject().getDataType().equals(DataType.JSON)) { validateJsonFile(config, event); } else { Optional validateur = ValidateurDAO.findByCodeTypeFichier(getCurrentObject().getTypeFichier().getCode()); if (!validateur.isPresent()) { Node source = (Node) event.getSource(); Stage parentStage = (Stage) source.getScene().getWindow(); NotificationDialog notificationDialog = new NotificationDialog("Validation impossible. Le type fichier " + getCurrentObject().getTypeFichier().getCode() + " n'a pas de validateur enregistré!", NotificationType.ERROR, parentStage); notificationDialog.showNotification(); } validateTexteFile(config, validateur.get(), event); } } private void validateTexteFile(Configuration config, Validateur validateur, ActionEvent event) { Task task = new Task() { @Override protected Void call() throws Exception { if (validateur.isConvertDataBeforeValidation()) { //On converti le fichier à valider en fichier generateAndParseTxtFile(getCurrentObject(), config, validateur); } return null; } }; task.setOnRunning(e -> LoadinIndicatorDialogUtil.getLoadingIndicatorDialog().show()); task.setOnFailed(e -> { LoadinIndicatorDialogUtil.getLoadingIndicatorDialog().hide(); Throwable th = task.getException(); if ((th instanceof ConfigException) || (th instanceof ValidatorException)) { Node source = (Node) event.getSource(); Stage parentStage = (Stage) source.getScene().getWindow(); NotificationDialog notificationDialog = new NotificationDialog(th.getMessage(), NotificationType.WARNING, parentStage); logger.warn(th.getMessage()); notificationDialog.showNotification(); } else { logger.error(task.getException()); AlertMessageUtil.showAlertException(task.getException(), "Une exception s'est produite pendant l'importation des données", "Erreur"); } }); task.setOnSucceeded(e -> { LoadinIndicatorDialogUtil.getLoadingIndicatorDialog().hide(); validateGeneratedFile(config, validateur, event); }); new Thread(task).start(); } private void validateGeneratedFile(Configuration config, Validateur validateur, ActionEvent event) { Task task = new Task() { @Override protected Boolean call() throws Exception { return validate(config, validateur); } }; task.setOnRunning(e -> LoadinIndicatorDialogUtil.getLoadingIndicatorDialog().show()); task.setOnSucceeded(e -> { LoadinIndicatorDialogUtil.getLoadingIndicatorDialog().hide(); Node source = (Node) event.getSource(); Stage parentStage = (Stage) source.getScene().getWindow(); boolean valid = task.getValue(); String message; NotificationDialog notificationDialog; String errorFileName = getCurrentObject().getTxtFilePath() != null ? new File(getCurrentObject().getTxtFilePath()).getName() : new File(getCurrentObject().getFilePath()).getName(); if (!valid) { message = "Echec de la validation. Le fichier contient des erreurs, veuillez consulter le répertoire " + config.getErrorDir() + ", puis et ouvrir le fichier d'erreur " + errorFileName + ".err pour en savoir plus"; notificationDialog = new NotificationDialog(message, NotificationType.ERROR, parentStage); } else { message = "Validation réussie. Fichier correcte"; notificationDialog = new NotificationDialog(message, NotificationType.SUCCESS, parentStage); } logger.error(message); notificationDialog.showNotification(); }); task.setOnFailed(e -> { LoadinIndicatorDialogUtil.getLoadingIndicatorDialog().hide(); Throwable th = task.getException(); if (th instanceof ConfigException || th instanceof ValidatorException) { Node source = (Node) event.getSource(); Stage parentStage = (Stage) source.getScene().getWindow(); NotificationDialog notificationDialog = new NotificationDialog(th.getMessage(), NotificationType.WARNING, parentStage); logger.warn(th.getMessage()); notificationDialog.showNotification(); } else { logger.error(th); AlertMessageUtil.showAlertException(th, "Une exception s'est produite pendant la validation du fichier", "Erreur"); } }); new Thread(task).start(); } /** * Méthode qui appelle la méthode de validation * * @param val : * @param config * @return * @throws Exception */ private boolean validate(Configuration config, Validateur validateur) throws Exception { if (config == null) { throw new ConfigException("Validation impossible, les répertoires ne sont pas configurés. Bien vouloir les configurer avant avant d'effectuer cette action"); } File originalFile = new File(getCurrentObject().getFilePath()); File file = validateur.isConvertDataBeforeValidation() ? new File(getCurrentObject().getTxtFilePath()) : originalFile; //Fichier à valider if (!file.exists()) { throw new FileNotFoundException("Le fichier " + file.getAbsolutePath() + " est introuvable"); } byte[] targetArray = IOUtils.toByteArray(FileToValidateEditDialogController.class.getClassLoader().getResourceAsStream("predicatelogic-engine.xml")); ConfigStreamValidator configValidator = new ConfigStreamValidator(targetArray, validateur.getContent(), config.getErrorDir(), config.getOutputDir(), file, originalFile); Validator validator = new Validator(); return validator.validate(configValidator, Boolean.TRUE, Boolean.TRUE, Utilities.getNbThreads()); } /** * Méthode qui génère et parse fichier txt à partir d'un fichier de données * csv, txt, ou excel * * @param val : objet contenant * @param config : objet contenant l'ensemeble des repertoires nécessaire à * l'extraction des données * @return : renvoie le chemin vers le fichier crée * @throws Exception */ private void generateAndParseTxtFile(FileToValidate fileToValidate, Configuration config, Validateur validateur) throws Exception { if (config == null) { throw new ConfigException("Validation impossible, veuillez configurer les repertoires avant d'effectuer cette action"); } String fileName = fileToValidate.getTypeFichier().getCode() + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + generateTierce() + ".txt"; File outputFile = new File(config.getDatasDir(), fileName); if (!outputFile.exists()) { //Creation du fichier outputFile.createNewFile(); } getCurrentObject().setTxtFilePath(outputFile.getAbsolutePath()); Set alphaNumeriqueToBeTruncated = new HashSet<>(); fileToValidate.getMetaAlphaNumeriqueFields().forEach(m -> { alphaNumeriqueToBeTruncated.add(m.getAlphaNumeriqueField()); }); switch (fileToValidate.getDataType()) { case TXT: FileToValidateDescription raw = new FileToValidateDescription(new File(fileToValidate.getFilePath()), fileToValidate.getDelimiteurLigne().getCode(), fileToValidate.getDelimiteurColonne().getCode()); if (fileToValidate.isStrictValidation()) { ImportData.parseFileByFieldLength(raw, validateur, outputFile, fileToValidate.isHeaderPresent()); } else { ImportData.parseFileCharacterByCharacter(raw, validateur, outputFile, fileToValidate.isHeaderPresent(), alphaNumeriqueToBeTruncated); } break; case CSV: raw = new FileToValidateDescription(new File(fileToValidate.getFilePath()), fileToValidate.getDelimiteurLigne().getCode(), fileToValidate.getDelimiteurColonne().getCode()); ImportData.parseCsvFile(raw, validateur, outputFile, fileToValidate.isHeaderPresent(), alphaNumeriqueToBeTruncated); break; case XLS: ImportData.parseXlsFile(fileToValidate.getFilePath(), fileToValidate.isHeaderPresent(), outputFile, validateur, alphaNumeriqueToBeTruncated); break; case XLSX: ImportData.parseXlsxFile(fileToValidate.getFilePath(), fileToValidate.isHeaderPresent(), outputFile, validateur, alphaNumeriqueToBeTruncated); break; default: break; } } private String generateTierce() { // Instance of random class Random rand = new Random(); int upperbound = 60; int random = rand.nextInt(upperbound); return String.format("%02d", random); } private boolean validateJson(FileToValidate fileToValidate, Configuration config) throws IOException { if (config == null) { throw new ConfigException("Validation impossible, les répertoires ne sont pas configurés. Bien vouloir les configurer avant avant d'effectuer cette action"); } TypeFichierJson typefichierJson = TypeFichierJsonDAO.getByTypeFichier(fileToValidate.getTypeFichier().getCode()); if (typefichierJson == null) { throw new ValidatorException("Validation impossible. Le type fichier " + fileToValidate.getTypeFichier().getCode() + " n'a pas de structure JSON enregistré"); } Validator validator = new Validator(); ConfigJsonValidator configJson = new ConfigJsonValidator( fileToValidate.getErrorFilePath(), config.getOutputDir(), new File(fileToValidate.getFilePath()), new TypeFichierJsonConverter(typefichierJson).convert() ); return validator.validate(configJson, System.getProperty("user.dir") + "\\src\\main\\java", true, true, Utilities.getNbThreads()); } private void validateJsonFile(Configuration config, ActionEvent event) { getCurrentObject().setErrorFilePath(Paths.get(config.getErrorDir(), getCurrentObject().getTypeFichier().getCode() + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + generateTierce() + "_JSON.txt").toString()); Task task = new Task() { @Override protected Boolean call() throws Exception { return validateJson(getCurrentObject(), config); } }; task.setOnRunning(e -> LoadinIndicatorDialogUtil.getLoadingIndicatorDialog().show()); task.setOnSucceeded(e -> { LoadinIndicatorDialogUtil.getLoadingIndicatorDialog().hide(); Node source = (Node) event.getSource(); Stage parentStage = (Stage) source.getScene().getWindow(); boolean valid = task.getValue(); String message; NotificationDialog notificationDialog; if (!valid) { message = "Echec de la validation. Le fichier contient des erreurs, veuillez consulter le répertoire " + config.getErrorDir() + ", puis ouvrir le fichier d'erreur " + new File(getCurrentObject().getErrorFilePath()).getName() + ".err pour en savoir plus"; notificationDialog = new NotificationDialog(message, NotificationType.ERROR, parentStage); } else { message = "Validation réussie. Fichier correcte"; notificationDialog = new NotificationDialog(message, NotificationType.SUCCESS, parentStage); } logger.error(message); notificationDialog.showNotification(); }); task.setOnFailed(e -> { LoadinIndicatorDialogUtil.getLoadingIndicatorDialog().hide(); Throwable th = task.getException(); if (th instanceof ConfigException || th instanceof ValidatorException) { Node source = (Node) event.getSource(); Stage parentStage = (Stage) source.getScene().getWindow(); NotificationDialog notificationDialog = new NotificationDialog(th.getMessage(), NotificationType.WARNING, parentStage); logger.warn(th.getMessage()); notificationDialog.showNotification(); } else { logger.error(th); AlertMessageUtil.showAlertException(th, "Une exception s'est produite pendant la validation du fichier", "Erreur"); } }); new Thread(task).start(); } }