diff --git a/src/main/java/ninja/javafx/smartcsv/FileWriter.java b/src/main/java/ninja/javafx/smartcsv/FileWriter.java new file mode 100644 index 0000000..e4dd45e --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/FileWriter.java @@ -0,0 +1,37 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 javafx.ninja + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +package ninja.javafx.smartcsv; + +import java.io.File; +import java.io.IOException; + +/** + * write some file + */ +public interface FileWriter { + void write(File filename) throws IOException; +} diff --git a/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java b/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java index e76fd6a..fb6f63a 100644 --- a/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java +++ b/src/main/java/ninja/javafx/smartcsv/csv/CSVFileReader.java @@ -51,7 +51,7 @@ public class CSVFileReader extends CSVConfigurable implements FileReader { ICsvMapReader mapReader = null; try { mapReader = new CsvMapReader(new java.io.FileReader(file.getAbsoluteFile()), csvPreference); - model = new CSVModel(file.getAbsolutePath()); + model = new CSVModel(); // the header columns are used as the keys to the Map String[] header = mapReader.getHeader(true); diff --git a/src/main/java/ninja/javafx/smartcsv/csv/CSVFileWriter.java b/src/main/java/ninja/javafx/smartcsv/csv/CSVFileWriter.java index 414a048..fc173f9 100644 --- a/src/main/java/ninja/javafx/smartcsv/csv/CSVFileWriter.java +++ b/src/main/java/ninja/javafx/smartcsv/csv/CSVFileWriter.java @@ -32,6 +32,7 @@ import org.springframework.stereotype.Service; import org.supercsv.io.CsvMapWriter; import org.supercsv.io.ICsvMapWriter; +import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Map; @@ -42,12 +43,19 @@ import static java.util.stream.Collectors.toMap; * filewriter for the csv */ @Service -public class CSVFileWriter extends CSVConfigurable { +public class CSVFileWriter extends CSVConfigurable implements ninja.javafx.smartcsv.FileWriter { - public void saveFile(CSVModel model) throws IOException { + private CSVModel model; + + public void setModel(CSVModel model) { + this.model = model; + } + + @Override + public void write(File filename) throws IOException { ICsvMapWriter mapWriter = null; try { - mapWriter = new CsvMapWriter(new FileWriter(model.getFilepath()), csvPreference); + mapWriter = new CsvMapWriter(new FileWriter(filename.getAbsolutePath()), csvPreference); mapWriter.writeHeader(model.getHeader()); for(CSVRow row: model.getRows()) { diff --git a/src/main/java/ninja/javafx/smartcsv/fx/SmartCSVController.java b/src/main/java/ninja/javafx/smartcsv/fx/SmartCSVController.java index 68b60fd..8006548 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/SmartCSVController.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/SmartCSVController.java @@ -28,8 +28,6 @@ package ninja.javafx.smartcsv.fx; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; -import javafx.concurrent.Service; -import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; @@ -38,6 +36,7 @@ import javafx.scene.layout.AnchorPane; import javafx.scene.layout.BorderPane; import javafx.stage.FileChooser; import ninja.javafx.smartcsv.FileReader; +import ninja.javafx.smartcsv.FileWriter; import ninja.javafx.smartcsv.csv.CSVFileReader; import ninja.javafx.smartcsv.csv.CSVFileWriter; import ninja.javafx.smartcsv.fx.about.AboutController; @@ -48,6 +47,8 @@ import ninja.javafx.smartcsv.fx.table.ValidationCellFactory; import ninja.javafx.smartcsv.fx.table.model.CSVModel; import ninja.javafx.smartcsv.fx.table.model.CSVRow; import ninja.javafx.smartcsv.fx.table.model.CSVValue; +import ninja.javafx.smartcsv.fx.util.LoadFileService; +import ninja.javafx.smartcsv.fx.util.SaveFileService; import ninja.javafx.smartcsv.preferences.PreferencesFileReader; import ninja.javafx.smartcsv.preferences.PreferencesFileWriter; import ninja.javafx.smartcsv.validation.ValidationError; @@ -66,6 +67,7 @@ import java.util.ResourceBundle; import static java.lang.Math.max; import static javafx.application.Platform.exit; import static javafx.application.Platform.runLater; +import static javafx.scene.layout.AnchorPane.*; /** * main controller of the application @@ -108,6 +110,12 @@ public class SmartCSVController extends FXMLController { @Autowired private PreferencesController preferencesController; + @Autowired + private LoadFileService loadFileService; + + @Autowired + private SaveFileService saveFileService;; + @FXML private BorderPane applicationPane; @@ -132,13 +140,13 @@ public class SmartCSVController extends FXMLController { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private ValidationCellFactory cellFactory; - private final LoadCSVService loadCSVService = new LoadCSVService(); - private final SaveCSVService saveCSVService = new SaveCSVService(); + private CSVModel model; private TableView tableView; - private File lastDirectory; private BooleanProperty fileChanged = new SimpleBooleanProperty(true); private ResourceBundle resourceBundle; + private File currentCsvFile; + private File currentConfigFile; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -148,7 +156,7 @@ public class SmartCSVController extends FXMLController { @Override public void initialize(URL location, ResourceBundle resourceBundle) { this.resourceBundle = resourceBundle; - saveCSVService.setWriter(csvFileWriter); + saveFileService.setWriter(csvFileWriter); cellFactory = new ValidationCellFactory(resourceBundle); errorList.setCellFactory(param -> new ValidationErrorListCell(resourceBundle)); errorList.getSelectionModel().selectedItemProperty().addListener(observable -> scrollToError()); @@ -177,22 +185,38 @@ public class SmartCSVController extends FXMLController { @FXML public void openCsv(ActionEvent actionEvent) { - loadFile(csvLoader, "CSV files (*.csv)", "*.csv", "Open CSV", csvName); + currentCsvFile = loadFile(csvLoader, + "CSV files (*.csv)", + "*.csv", + "Open CSV", + currentCsvFile); + setCsvFileName(); } @FXML public void openConfig(ActionEvent actionEvent) { - loadFile(validationLoader, "JSON files (*.json)", "*.json", "Open Validation Configuration", configurationName); + currentConfigFile = loadFile(validationLoader, + "JSON files (*.json)", + "*.json", + "Open Validation Configuration", + currentConfigFile); + setConfigFileName(); } @FXML public void saveCsv(ActionEvent actionEvent) { - saveCSVService.restart(); + csvFileWriter.setModel(model); + useSaveFileService(csvFileWriter, currentCsvFile); } @FXML public void saveAsCsv(ActionEvent actionEvent) { - saveFile(csvFileWriter, "CSV files (*.csv)", "*.csv"); + csvFileWriter.setModel(model); + currentCsvFile = saveFile(csvFileWriter, + "CSV files (*.csv)", + "*.csv", + currentCsvFile); + setCsvFileName(); } @FXML @@ -247,21 +271,34 @@ public class SmartCSVController extends FXMLController { // private methods //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - private void loadCsvPreferences() { - try { - if (PREFERENCES_FILE.exists()) { - preferencesLoader.read(PREFERENCES_FILE); - } - setCsvPreference(preferencesLoader.getCSVpreference()); - } catch (IOException e) { - e.printStackTrace(); + private void setCsvFileName() { + if (currentCsvFile != null) { + csvName.setText(currentCsvFile.getName()); + } else { + csvName.setText(""); } } + private void setConfigFileName() { + if (currentConfigFile != null) { + configurationName.setText(currentConfigFile.getName()); + } else { + configurationName.setText(""); + } + } + + private void loadCsvPreferences() { + if (PREFERENCES_FILE.exists()) { + useLoadFileService(preferencesLoader, PREFERENCES_FILE); + } + setCsvPreference(preferencesLoader.getCSVpreference()); + } + private void saveCsvPreferences(CsvPreference csvPreference) { try { createPreferenceFile(); - preferencesWriter.saveFile(PREFERENCES_FILE, csvPreference); + preferencesWriter.setCsvPreference(csvPreference); + useSaveFileService(preferencesWriter, PREFERENCES_FILE); } catch (IOException e) { e.printStackTrace(); } @@ -286,7 +323,11 @@ public class SmartCSVController extends FXMLController { preferencesController.setCsvPreference(csvPreference); } - private void loadFile(FileReader fileReader, String filterText, String filter, String title, Label fileLabel) { + private File loadFile(FileReader fileReader, + String filterText, + String filter, + String title, + File initChildFile) { final FileChooser fileChooser = new FileChooser(); //Set extension filter @@ -294,21 +335,22 @@ public class SmartCSVController extends FXMLController { fileChooser.getExtensionFilters().add(extFilter); fileChooser.setTitle(title); - if (lastDirectory != null) { - fileChooser.setInitialDirectory(lastDirectory); + if (initChildFile != null) { + fileChooser.setInitialDirectory(initChildFile.getParentFile()); } //Show open file dialog - final File file = fileChooser.showOpenDialog(applicationPane.getScene().getWindow()); + File file = fileChooser.showOpenDialog(applicationPane.getScene().getWindow()); if (file != null) { - loadCSVService.setFileLabel(fileLabel); - loadCSVService.setFile(file); - loadCSVService.setFileReader(fileReader); - loadCSVService.restart(); + useLoadFileService(fileReader, file); + return file; + } else { + return initChildFile; } } - private void saveFile(CSVFileWriter writer, String filterText, String filter) { + private File saveFile(FileWriter writer, String filterText, String filter, File initFile) { + File file = initFile; if (model != null) { final FileChooser fileChooser = new FileChooser(); @@ -316,19 +358,39 @@ public class SmartCSVController extends FXMLController { final FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(filterText, filter); fileChooser.getExtensionFilters().add(extFilter); - File initfile = new File(model.getFilepath()); - fileChooser.setInitialDirectory(initfile.getParentFile()); - fileChooser.setInitialFileName(initfile.getName()); + if (initFile != null) { + fileChooser.setInitialDirectory(initFile.getParentFile()); + fileChooser.setInitialFileName(initFile.getName()); + } fileChooser.setTitle("Save File"); //Show open file dialog - final File file = fileChooser.showOpenDialog(applicationPane.getScene().getWindow()); + file = fileChooser.showSaveDialog(applicationPane.getScene().getWindow()); if (file != null) { - model.setFilepath(file.getAbsolutePath()); - saveCSVService.setWriter(writer); - saveCSVService.restart(); + useSaveFileService(writer, file); } } + return file; + } + + private void useLoadFileService(FileReader fileReader, File file) { + loadFileService.setFile(file); + loadFileService.setFileReader(fileReader); + loadFileService.restart(); + loadFileService.setOnSucceeded(event -> runLater(() -> { + resetContent(); + fileChanged.setValue(false); + })); + } + + private void useSaveFileService(FileWriter writer, File file) { + saveFileService.setFile(file); + saveFileService.setWriter(writer); + saveFileService.restart(); + saveFileService.setOnSucceeded(event -> runLater(() -> { + resetContent(); + fileChanged.setValue(false); + })); } /** @@ -346,10 +408,10 @@ public class SmartCSVController extends FXMLController { tableView.getItems().setAll(model.getRows()); tableView.setEditable(true); - AnchorPane.setBottomAnchor(tableView, 0.0); - AnchorPane.setTopAnchor(tableView, 0.0); - AnchorPane.setLeftAnchor(tableView, 0.0); - AnchorPane.setRightAnchor(tableView, 0.0); + setBottomAnchor(tableView, 0.0); + setTopAnchor(tableView, 0.0); + setLeftAnchor(tableView, 0.0); + setRightAnchor(tableView, 0.0); tableWrapper.getChildren().setAll(tableView); errorList.setItems(model.getValidationError()); @@ -404,85 +466,4 @@ public class SmartCSVController extends FXMLController { stateName.setText(""); } } - - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // inner class - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Service class for async load of a csv file - */ - private class LoadCSVService extends Service { - - private File file = null; - private FileReader fileReader; - private Label fileLabel; - - public void setFile(File value) { - file = value; - } - public void setFileReader(FileReader fileReader) { - this.fileReader = fileReader; - } - public void setFileLabel(Label fileLabel) { - this.fileLabel = fileLabel; - } - - @Override - protected Task createTask() { - return new Task() { - @Override - protected Void call() throws Exception { - if (file != null) { - try { - lastDirectory = file.getParentFile(); - fileReader.read(file); - runLater(() -> { - fileLabel.setText(file.getName()); - resetContent(); - fileChanged.setValue(false); - }); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - return null; - } - }; - } - - } - - /** - * Service class for async load of a csv file - */ - private class SaveCSVService extends Service { - - private CSVFileWriter writer; - - public void setWriter(CSVFileWriter writer) { - this.writer = writer; - } - - @Override - protected Task createTask() { - return new Task() { - @Override - protected Void call() throws Exception { - try { - writer.saveFile(model); - runLater(() -> { - resetContent(); - fileChanged.setValue(false); - }); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return null; - } - }; - } - - } } diff --git a/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVModel.java b/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVModel.java index 7e5d720..ba0d489 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVModel.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/table/model/CSVModel.java @@ -40,21 +40,8 @@ public class CSVModel { private Validator validator; private ObservableList rows = FXCollections.observableArrayList(); private String[] header; - private String filepath; private ObservableList validationError = FXCollections.observableArrayList(); - public CSVModel(String filepath) { - this.filepath = filepath; - } - - public String getFilepath() { - return this.filepath; - } - - public void setFilepath(String filepath) { - this.filepath = filepath; - } - /** * sets the validator for the data revalidates * @param validator the validator for this data diff --git a/src/main/java/ninja/javafx/smartcsv/fx/util/LoadFileService.java b/src/main/java/ninja/javafx/smartcsv/fx/util/LoadFileService.java new file mode 100644 index 0000000..d8269ac --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/fx/util/LoadFileService.java @@ -0,0 +1,63 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 javafx.ninja + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +package ninja.javafx.smartcsv.fx.util; + +import javafx.concurrent.Service; +import javafx.concurrent.Task; +import ninja.javafx.smartcsv.FileReader; + +import java.io.File; + +/** + * Service class for async load of a csv file + */ +@org.springframework.stereotype.Service +public class LoadFileService extends Service { + + private File file; + private FileReader fileReader; + + public void setFile(File value) { + file = value; + } + public void setFileReader(FileReader fileReader) { + this.fileReader = fileReader; + } + + @Override + protected Task createTask() { + return new Task() { + @Override + protected Void call() throws Exception { + if (file != null) { + fileReader.read(file); + } + return null; + } + }; + } +} diff --git a/src/main/java/ninja/javafx/smartcsv/fx/util/SaveFileService.java b/src/main/java/ninja/javafx/smartcsv/fx/util/SaveFileService.java new file mode 100644 index 0000000..3941995 --- /dev/null +++ b/src/main/java/ninja/javafx/smartcsv/fx/util/SaveFileService.java @@ -0,0 +1,70 @@ +/* + The MIT License (MIT) + ----------------------------------------------------------------------------- + + Copyright (c) 2015 javafx.ninja + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +package ninja.javafx.smartcsv.fx.util; + +import javafx.concurrent.Service; +import javafx.concurrent.Task; +import ninja.javafx.smartcsv.FileWriter; +import ninja.javafx.smartcsv.csv.CSVFileWriter; + +import java.io.File; + +import static javafx.application.Platform.runLater; + +/** + * Service class for async load of a csv file + */ +@org.springframework.stereotype.Service +public class SaveFileService extends Service { + + private File file; + private FileWriter writer; + + public void setWriter(FileWriter writer) { + this.writer = writer; + } + + public void setFile(File value) { + file = value; + } + + @Override + protected Task createTask() { + return new Task() { + @Override + protected Void call() throws Exception { + try { + writer.write(file); + } catch (Throwable ex) { + ex.printStackTrace(); + } + return null; + } + }; + } + +} diff --git a/src/main/java/ninja/javafx/smartcsv/preferences/PreferencesFileWriter.java b/src/main/java/ninja/javafx/smartcsv/preferences/PreferencesFileWriter.java index 516705f..c295855 100644 --- a/src/main/java/ninja/javafx/smartcsv/preferences/PreferencesFileWriter.java +++ b/src/main/java/ninja/javafx/smartcsv/preferences/PreferencesFileWriter.java @@ -29,23 +29,29 @@ package ninja.javafx.smartcsv.preferences; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; import com.typesafe.config.ConfigRenderOptions; +import ninja.javafx.smartcsv.FileWriter; import org.springframework.stereotype.Service; import org.supercsv.prefs.CsvPreference; import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.util.HashMap; import java.util.Map; -import static java.nio.file.Files.write; - /** * Save preferences to configuration file */ @Service -public class PreferencesFileWriter { +public class PreferencesFileWriter implements FileWriter { - public void saveFile(File file, CsvPreference csvPreference) throws IOException { + private CsvPreference csvPreference; + + public void setCsvPreference(CsvPreference csvPreference) { + this.csvPreference = csvPreference; + } + + public void write(File file) throws IOException { Map preferences = new HashMap<>(); preferences.put("quoteChar", Character.toString(csvPreference.getQuoteChar())); preferences.put("delimiterChar", Character.toString((char)csvPreference.getDelimiterChar())); @@ -55,7 +61,7 @@ public class PreferencesFileWriter { preferences.put("quoteMode", QuoteModeHelper.getQuoteModeName(csvPreference.getQuoteMode())); Config config = ConfigFactory.parseMap(preferences); - write(file.toPath(), config.root().render(ConfigRenderOptions.concise()).getBytes()); + Files.write(file.toPath(), config.root().render(ConfigRenderOptions.concise()).getBytes()); } }