All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.fraunhofer.iosb.ilt.frostserver.modeleditor.FXMLController Maven / Gradle / Ivy

/*
 * Copyright (C) 2024 Fraunhofer Institut IOSB, Fraunhoferstr. 1, D 76131
 * Karlsruhe, Germany.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 */
package de.fraunhofer.iosb.ilt.frostserver.modeleditor;

import com.fasterxml.jackson.core.JsonProcessingException;
import de.fraunhofer.iosb.ilt.configurable.ConfigEditor;
import de.fraunhofer.iosb.ilt.frostserver.json.serialize.JsonWriter;
import de.fraunhofer.iosb.ilt.frostserver.model.loader.DefModel;
import de.fraunhofer.iosb.ilt.frostserver.modeleditor.LiquibaseTemplates.ChangeLogBuilder;
import de.fraunhofer.iosb.ilt.frostserver.util.SecurityModel;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextField;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Window;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;

public class FXMLController implements Initializable {

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(FXMLController.class);

    @FXML
    private AnchorPane paneRoot;
    @FXML
    private SplitPane splitPaneModel;
    @FXML
    private ScrollPane paneConfig;
    @FXML
    private BorderPane bpEntityModel;
    @FXML
    private BorderPane bpSecurityModel;
    @FXML
    private Button buttonLoad;
    @FXML
    private Button buttonSave;
    @FXML
    private Button buttonSaveAll;
    @FXML
    private Button buttonClose;
    @FXML
    private TextField textFieldIndent;
    @FXML
    private TextField textFieldAuthor;
    @FXML
    private TextField textFieldDate;
    @FXML
    private TextField textFieldLiquibasePath;
    @FXML
    private Label labelFile;
    @FXML
    private ScrollPane paneConfigSec;
    @FXML
    private Button buttonLoadSec;
    @FXML
    private Button buttonSaveSec;
    @FXML
    private Label labelFileSec;
    @FXML
    private ListView listViewEntityTypes;
    private ObservableList entityTypeList;

    private ConfigFileEditor cfeSecurity;
    private File currentPath;

    @FXML
    private void actionLoad(ActionEvent event) {
        loadWithSelector();
    }

    @FXML
    private void actionSave(ActionEvent event) {
        FileData fd = listViewEntityTypes.getSelectionModel().getSelectedItem();
        ConfigFileEditor cfe = fd.getEditor();
        cfe.saveModelWithChooser("Save Data Model", getWindow());
        fd.updateFileName();
    }

    @FXML
    private void actionSaveAll(ActionEvent event) {
        final String indentText = StringUtils.defaultString(textFieldIndent.getText());
        List models = new ArrayList<>();
        for (FileData fd : listViewEntityTypes.getItems()) {
            ConfigFileEditor cfe = fd.getEditor();
            try {
                String data = cfe.saveConfigToCurrentFile(indentText);
                DefModel value = JsonWriter.getObjectMapper().readValue(data, DefModel.class);
                models.add(value);
            } catch (JsonProcessingException ex) {
                LOGGER.error("Failed to parse.", ex);
            } catch (IllegalArgumentException ex) {
                LOGGER.error("Failed to save.", ex);
            }
        }
        final String dateText = textFieldDate.getText();
        final String authorText = StringUtils.defaultIfBlank(textFieldAuthor.getText(), "generated");
        List liquibaseChangeLogs = LiquibaseTemplates.CreateChangeLogsFor(models, dateText, authorText);
        File liquibasePath = new File(currentPath, textFieldLiquibasePath.getText());
        if (!liquibaseChangeLogs.isEmpty()) {
            liquibasePath.mkdirs();
        }
        for (var cl : liquibaseChangeLogs) {
            String data = cl.build();
            String fileName = cl.getFileName();
            if (!fileName.endsWith(".xml")) {
                fileName += ".xml";
            }
            File targetFile = new File(liquibasePath, fileName);
            try {
                FileUtils.writeStringToFile(targetFile, data, StandardCharsets.UTF_8);
            } catch (IOException ex) {
                LOGGER.error("Failed to save liquibase file.", ex);
            }
        }

    }

    @FXML
    private void actionAdd(ActionEvent event) {
        ConfigFileEditor cfe = new ConfigFileEditor(DefModel.class);
        cfe.initialize();
        addToList(cfe);
    }

    @FXML
    private void actionClose(ActionEvent event) {
        FileData fd = listViewEntityTypes.getSelectionModel().getSelectedItem();
        if (fd != null) {
            listViewEntityTypes.getItems().remove(fd);
        }
    }

    @FXML
    private void actionCloseAll(ActionEvent event) {
        for (Iterator it = listViewEntityTypes.getItems().iterator(); it.hasNext();) {
            FileData fd = it.next();
            it.remove();
        }
    }

    private Window getWindow() {
        return paneRoot.getScene().getWindow();
    }

    @FXML
    private void actionLoadSec(ActionEvent event) {
        loadSecWithSelector();
    }

    @FXML
    private void actionSaveSec(ActionEvent event) {
        cfeSecurity.saveModelWithChooser("Save Security Model", getWindow());
        labelFileSec.setText(cfeSecurity.getCurrentFile().getAbsolutePath());
    }

    private void loadWithSelector() {
        ConfigFileEditor cfe = new ConfigFileEditor(DefModel.class);
        cfe.loadFromFileWithChooser("Load Entity Type", getWindow());
        addToList(cfe);
    }

    private void loadFromFile(File file) {
        ConfigFileEditor cfe = new ConfigFileEditor(DefModel.class);
        cfe.loadFromFile(file);
        addToList(cfe);
    }

    private void loadSecWithSelector() {
        cfeSecurity.loadFromFileWithChooser("Load Security Model", getWindow());
        labelFileSec.setText(cfeSecurity.getCurrentFile().getAbsolutePath());
        replaceSecEditor(cfeSecurity.getConfigEditor());
    }

    private void loadSecFromFile(File file) {
        cfeSecurity.loadFromFile(file);
        labelFileSec.setText(cfeSecurity.getCurrentFile().getAbsolutePath());
        replaceSecEditor(cfeSecurity.getConfigEditor());
    }

    private void addToList(ConfigFileEditor cfe) {
        FileData fd = new FileData();
        fd.setEditor(cfe);
        fd.updateFileName();
        entityTypeList.add(fd);
        listViewEntityTypes.getSelectionModel().select(fd);
    }

    private void showModel(FileData file) {
        if (file == null) {
            paneConfig.setContent(null);
            return;
        }
        LOGGER.info("Selected: {}", file);
        replaceEditor(file.editor);
        labelFile.setText(file.getCurrentFilePath());
    }

    private void replaceEditor(ConfigFileEditor editor) {
        if (editor == null) {
            paneConfig.setContent(null);
        } else {
            replaceEditor(editor.getConfigEditor());
            File currentFile = editor.getCurrentFile();
            if (currentFile != null) {
                currentPath = currentFile.getParentFile();
            }
        }
    }

    private void replaceEditor(ConfigEditor editor) {
        if (editor == null) {
            paneConfig.setContent(null);
        } else {
            paneConfig.setContent(editor.getGuiFactoryFx().getNode());
        }
    }

    private void replaceSecEditor(ConfigEditor editor) {
        if (editor == null) {
            paneConfigSec.setContent(null);
        } else {
            paneConfigSec.setContent(editor.getGuiFactoryFx().getNode());
        }
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        SplitPane.setResizableWithParent(listViewEntityTypes, Boolean.FALSE);
        cfeSecurity = new ConfigFileEditor(SecurityModel.class);
        cfeSecurity.initialize();
        entityTypeList = FXCollections.observableArrayList();
        listViewEntityTypes.setItems(entityTypeList);
        listViewEntityTypes.getSelectionModel().selectedItemProperty().addListener((ov, oldItem, newItem) -> showModel(newItem));
        makeDropTarget(bpEntityModel, this::loadFromFile);
        makeDropTarget(bpSecurityModel, this::loadSecFromFile);
        textFieldDate.setText(DateTimeFormatter.ISO_LOCAL_DATE.format(ZonedDateTime.now()));
        textFieldLiquibasePath.setText("../liquibase");
    }

    public static void makeDropTarget(Node node, FileAction action) {
        node.setOnDragOver(event -> {
            if (event.getGestureSource() != node && event.getDragboard().hasFiles()) {
                event.acceptTransferModes(TransferMode.COPY);
            }
            event.consume();
        });
        node.setOnDragDropped(event -> {
            Dragboard db = event.getDragboard();
            boolean success = false;
            if (db.hasFiles()) {
                List files = db.getFiles();
                for (var file : files) {
                    action.call(file);
                }
                success = true;
            }
            event.setDropCompleted(success);
            event.consume();
        });
    }

    public void close() {
        LOGGER.info("Received close, shutting down.");
    }

    public static class FileData {

        private String fileName;
        private ConfigFileEditor editor;

        public String getFileName() {
            return fileName;
        }

        public File getCurrentFile() {
            return editor.getCurrentFile();
        }

        public String getCurrentFilePath() {
            File currentFile = editor.getCurrentFile();
            if (currentFile == null) {
                return "No file selected";
            }
            return currentFile.getAbsolutePath();
        }

        public ConfigFileEditor getEditor() {
            return editor;
        }

        public FileData setEditor(ConfigFileEditor editor) {
            this.editor = editor;
            return this;
        }

        public FileData updateFileName() {
            File currentFile = editor.getCurrentFile();
            if (currentFile == null) {
                fileName = "No File";
            } else {
                fileName = currentFile.getName();
            }
            return this;
        }

        @Override
        public String toString() {
            return fileName;
        }

    }

    public static interface FileAction {

        abstract public void call(File file);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy