diff --git a/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java b/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java index 103917eccad00747a657904f9d2bb3af6526744b..ad344823192657c89d1b1d4d902e60efb33df3ee 100644 --- a/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java +++ b/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java @@ -335,4 +335,21 @@ public class ServerConnection BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); reader.close(); } + + public String exportDatabase() throws Exception + { + URL url = new URL(settings.getUrl() + "/database?secret=" + Helpers.getURLEncodedString(settings.getSecret())); + HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection(); + httpsCon.setDoOutput(true); + httpsCon.setRequestMethod("GET"); + + if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK) + { + return Read.getStringFromInputStream(httpsCon.getInputStream()); + } + else + { + return null; + } + } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/logic/Utils.java b/src/de/deadlocker8/budgetmaster/logic/Utils.java index 55789dca5c6081740ca9e6a6fb2d427eda140c45..79ba8e1906f783abc0fe3c05ff02ec64364fae8e 100644 --- a/src/de/deadlocker8/budgetmaster/logic/Utils.java +++ b/src/de/deadlocker8/budgetmaster/logic/Utils.java @@ -12,6 +12,7 @@ import java.util.ResourceBundle; import com.google.gson.Gson; +import de.deadlocker8.budgetmasterserver.main.Database; import tools.PathUtils; public class Utils @@ -45,4 +46,29 @@ public class Utils writer.write(jsonString); writer.close(); } + + public static Database loadDatabaseJSON(File file) + { + Database database; + try + { + Gson gson = new Gson(); + PathUtils.checkFolder(file.getParentFile()); + Reader reader = Files.newBufferedReader(Paths.get(file.getAbsolutePath()), Charset.forName("UTF-8")); + database = gson.fromJson(reader, Database.class); + reader.close(); + return database; + } + catch(IOException e) + { + return null; + } + } + + public static void saveDatabaseJSON(File file, String databaseJSON) throws IOException + { + Writer writer = Files.newBufferedWriter(Paths.get(file.getAbsolutePath()), Charset.forName("UTF-8")); + writer.write(databaseJSON); + writer.close(); + } } \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmaster/ui/Controller.java b/src/de/deadlocker8/budgetmaster/ui/Controller.java index f265abba380075bdc74a86b98de17d449a0b4986..0e4f6d278ca132c9f3ce30d084547a2e13c225d7 100644 --- a/src/de/deadlocker8/budgetmaster/ui/Controller.java +++ b/src/de/deadlocker8/budgetmaster/ui/Controller.java @@ -310,7 +310,7 @@ public class Controller { try { - ServerConnection connection = new ServerConnection(settings); + ServerConnection connection = new ServerConnection(settings); paymentHandler = new PaymentHandler(); paymentHandler.getPayments().addAll(connection.getPayments(currentDate.getYear(), currentDate.getMonthOfYear())); diff --git a/src/de/deadlocker8/budgetmaster/ui/SettingsController.java b/src/de/deadlocker8/budgetmaster/ui/SettingsController.java index ad3d1a6ff5fd5b94071f86ff49d91d36c6307c65..ac6f9aba6f8f7dc621309fb621c84ad96ab36021 100644 --- a/src/de/deadlocker8/budgetmaster/ui/SettingsController.java +++ b/src/de/deadlocker8/budgetmaster/ui/SettingsController.java @@ -1,5 +1,6 @@ package de.deadlocker8.budgetmaster.ui; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Optional; @@ -22,6 +23,7 @@ import javafx.scene.control.TextField; import javafx.scene.control.TextInputDialog; import javafx.scene.control.ToggleGroup; import javafx.scene.layout.AnchorPane; +import javafx.stage.FileChooser; import javafx.stage.Modality; import javafx.stage.Stage; import logger.Logger; @@ -124,8 +126,8 @@ public class SettingsController { AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte gib deine gewünschte Währung ein!", controller.getIcon(), controller.getStage(), null, false); return; - } - + } + ArrayList<String> trustedHosts = new ArrayList<>(); String trustedHostText = textAreaTrustedHosts.getText(); String[] trustedHostsArray = trustedHostText.split("\n"); @@ -140,12 +142,12 @@ public class SettingsController setTextAreaTrustedHosts(trustedHosts); if(controller.getSettings() != null) - { + { if(!secret.equals("******")) { controller.getSettings().setSecret(HashUtils.hash(secret, Helpers.SALT)); - } - controller.getSettings().setUrl(url); + } + controller.getSettings().setUrl(url); controller.getSettings().setCurrency(currency); controller.getSettings().setRestActivated(radioButtonRestActivated.isSelected()); controller.getSettings().setTrustedHosts(trustedHosts); @@ -179,7 +181,39 @@ public class SettingsController public void backupDB() { + FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("Datenbank exportieren"); + FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("JSON (*.json)", "*.json"); + fileChooser.getExtensionFilters().add(extFilter); + File file = fileChooser.showSaveDialog(controller.getStage()); + if(file != null) + { + Stage modalStage = showModal("Vorgang läuft", "Die Datenbank wird exportiert, bitte warten..."); + Worker.runLater(() -> { + try + { + ServerConnection connection = new ServerConnection(controller.getSettings()); + String databaseJSON = connection.exportDatabase(); + Utils.saveDatabaseJSON(file, databaseJSON); + + Platform.runLater(() -> { + if(modalStage != null) + { + modalStage.close(); + } + AlertGenerator.showAlert(AlertType.INFORMATION, "Erfolgreich exportiert", "", "Die Datenbank wurder erfolgreich exportiert.", controller.getIcon(), controller.getStage(), null, false); + }); + } + catch(Exception e) + { + Logger.error(e); + Platform.runLater(() -> { + controller.showConnectionErrorAlert(e.getMessage()); + }); + } + }); + } } public void deleteDB() diff --git a/src/de/deadlocker8/budgetmasterserver/main/Database.java b/src/de/deadlocker8/budgetmasterserver/main/Database.java new file mode 100644 index 0000000000000000000000000000000000000000..e4d927792ff3c9377a634e99735ca18f82da0cf6 --- /dev/null +++ b/src/de/deadlocker8/budgetmasterserver/main/Database.java @@ -0,0 +1,41 @@ +package de.deadlocker8.budgetmasterserver.main; + +import java.util.ArrayList; + +import de.deadlocker8.budgetmaster.logic.Category; +import de.deadlocker8.budgetmaster.logic.NormalPayment; +import de.deadlocker8.budgetmaster.logic.RepeatingPayment; + +public class Database +{ + private ArrayList<Category> categories; + private ArrayList<NormalPayment> normalPayments; + private ArrayList<RepeatingPayment> repeatingPayments; + + public Database() + { + + } + + public Database(ArrayList<Category> categories, ArrayList<NormalPayment> normalPayments, ArrayList<RepeatingPayment> repeatingPayments) + { + this.categories = categories; + this.normalPayments = normalPayments; + this.repeatingPayments = repeatingPayments; + } + + public ArrayList<Category> getCategories() + { + return categories; + } + + public ArrayList<NormalPayment> getNormalPayments() + { + return normalPayments; + } + + public ArrayList<RepeatingPayment> getRepeatingPayments() + { + return repeatingPayments; + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/main/DatabaseExporter.java b/src/de/deadlocker8/budgetmasterserver/main/DatabaseExporter.java new file mode 100644 index 0000000000000000000000000000000000000000..c89d0ba1e058dd8357f915d9b8667b2599eb710f --- /dev/null +++ b/src/de/deadlocker8/budgetmasterserver/main/DatabaseExporter.java @@ -0,0 +1,171 @@ +package de.deadlocker8.budgetmasterserver.main; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; + +import de.deadlocker8.budgetmaster.logic.Category; +import de.deadlocker8.budgetmaster.logic.NormalPayment; +import de.deadlocker8.budgetmaster.logic.RepeatingPayment; +import javafx.scene.paint.Color; +import logger.Logger; + +public class DatabaseExporter +{ + private Connection connection; + + public DatabaseExporter(Settings settings) throws IllegalStateException + { + try + { + this.connection = DriverManager.getConnection(settings.getDatabaseUrl() + settings.getDatabaseName() + "?useLegacyDatetimeCode=false&serverTimezone=Europe/Berlin", settings.getDatabaseUsername(), settings.getDatabasePassword()); + } + catch(Exception e) + { + Logger.error(e); + throw new IllegalStateException("Cannot connect the database!", e); + } + } + + public Database exportDatabase() + { + ArrayList<Category> categories = getAllCategories(); + ArrayList<NormalPayment> normalPayments = getAllNormalPayments(); + ArrayList<RepeatingPayment> repeatingPayments = getAllRepeatingPayments(); + + return new Database(categories, normalPayments, repeatingPayments); + } + + private ArrayList<Category> getAllCategories() + { + Statement stmt = null; + String query = "SELECT * FROM category ORDER BY category.ID"; + ArrayList<Category> results = new ArrayList<>(); + try + { + stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery(query); + while(rs.next()) + { + int id = rs.getInt("ID"); + String name = rs.getString("Name"); + String color = rs.getString("Color"); + + results.add(new Category(id, name, Color.web(color))); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + if(stmt != null) + { + try + { + stmt.close(); + } + catch(SQLException e) + { + } + } + } + + return results; + } + + private ArrayList<NormalPayment> getAllNormalPayments() + { + Statement stmt = null; + String query = "SELECT * FROM payment;"; + + ArrayList<NormalPayment> results = new ArrayList<>(); + try + { + stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery(query); + + while(rs.next()) + { + int resultID = rs.getInt("ID"); + String name = rs.getString("Name"); + int amount = rs.getInt("amount"); + String date = rs.getString("Date"); + int categoryID = rs.getInt("CategoryID"); + String description = rs.getString("Description"); + + results.add(new NormalPayment(resultID, amount, date, categoryID, name, description)); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + if(stmt != null) + { + try + { + stmt.close(); + } + catch(SQLException e) + { + } + } + } + + return results; + } + + private ArrayList<RepeatingPayment> getAllRepeatingPayments() + { + Statement stmt = null; + String query = "SELECT * FROM repeating_payment;"; + + ArrayList<RepeatingPayment> results = new ArrayList<>(); + try + { + stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery(query); + + while(rs.next()) + { + int resultID = rs.getInt("ID"); + String name = rs.getString("Name"); + String description = rs.getString("Description"); + int amount = rs.getInt("amount"); + String date = rs.getString("Date"); + int categoryID = rs.getInt("CategoryID"); + int repeatInterval = rs.getInt("RepeatInterval"); + String repeatEndDate = rs.getString("RepeatEndDate"); + int repeatMonthDay = rs.getInt("RepeatMonthDay"); + + results.add(new RepeatingPayment(resultID, amount, date, categoryID, name, description, repeatInterval, repeatEndDate, repeatMonthDay)); + } + } + catch(SQLException e) + { + Logger.error(e); + } + finally + { + if(stmt != null) + { + try + { + stmt.close(); + } + catch(SQLException e) + { + } + } + } + + return results; + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/main/DatabaseImporter.java b/src/de/deadlocker8/budgetmasterserver/main/DatabaseImporter.java new file mode 100644 index 0000000000000000000000000000000000000000..9cc06ac18c1ba34b18de4c04089534e6e6193623 --- /dev/null +++ b/src/de/deadlocker8/budgetmasterserver/main/DatabaseImporter.java @@ -0,0 +1,44 @@ +package de.deadlocker8.budgetmasterserver.main; + +import java.sql.Connection; +import java.sql.DriverManager; + +import logger.Logger; + +public class DatabaseImporter +{ + private Connection connection; + + public DatabaseImporter(Settings settings) throws IllegalStateException + { + try + { + this.connection = DriverManager.getConnection(settings.getDatabaseUrl() + settings.getDatabaseName() + "?useLegacyDatetimeCode=false&serverTimezone=Europe/Berlin", settings.getDatabaseUsername(), settings.getDatabasePassword()); + } + catch(Exception e) + { + Logger.error(e); + throw new IllegalStateException("Cannot connect the database!", e); + } + } + + public void importDatabase(Database database) + { + + } + + private void importCategories() + { + //TODO + } + + private void importNormalPayments() + { + //TODO + } + + private void importRepeatingPayments() + { + //TODO + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java b/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java index 0b47774b2edfef2f779f49321665d32101dedead..21a9a66b34be6438dcc1d998b638af8380d2d4ad 100644 --- a/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java +++ b/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java @@ -27,6 +27,8 @@ import de.deadlocker8.budgetmasterserver.server.category.CategoryGetAll; import de.deadlocker8.budgetmasterserver.server.category.CategoryUpdate; import de.deadlocker8.budgetmasterserver.server.categorybudget.CategoryBudgetGet; import de.deadlocker8.budgetmasterserver.server.database.DatabaseDelete; +import de.deadlocker8.budgetmasterserver.server.database.DatabaseExport; +import de.deadlocker8.budgetmasterserver.server.database.DatabaseImport; import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentAdd; import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentDelete; import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentGet; @@ -115,6 +117,8 @@ public class SparkServer get("/rest", new RestGet(handler, gson)); // Database + get("/database", new DatabaseExport(settings, gson)); + put("/database", new DatabaseImport(handler, settings)); delete("/database", new DatabaseDelete(handler, settings)); after((request, response) -> { diff --git a/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseExport.java b/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseExport.java new file mode 100644 index 0000000000000000000000000000000000000000..0da86d757a68face190dd8c00d9901593b61a901 --- /dev/null +++ b/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseExport.java @@ -0,0 +1,41 @@ +package de.deadlocker8.budgetmasterserver.server.database; + +import static spark.Spark.halt; + +import com.google.gson.Gson; + +import de.deadlocker8.budgetmasterserver.main.DatabaseExporter; +import de.deadlocker8.budgetmasterserver.main.Settings; +import logger.Logger; +import spark.Request; +import spark.Response; +import spark.Route; + +public class DatabaseExport implements Route +{ + private Settings settings; + private Gson gson; + + public DatabaseExport(Settings settings, Gson gson) + { + this.settings = settings; + this.gson = gson; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + try + { + DatabaseExporter exporter = new DatabaseExporter(settings); + return gson.toJson(exporter.exportDatabase()); + } + catch(Exception e) + { + Logger.error(e); + halt(500, "Internal Server Error"); + } + + return null; + } +} \ No newline at end of file diff --git a/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseImport.java b/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseImport.java new file mode 100644 index 0000000000000000000000000000000000000000..9d6939017fd00132fbcad613629c9939ae0ee7bd --- /dev/null +++ b/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseImport.java @@ -0,0 +1,70 @@ +package de.deadlocker8.budgetmasterserver.server.database; + +import static spark.Spark.halt; + +import java.util.ArrayList; + +import org.joda.time.DateTime; + +import com.google.gson.Gson; + +import de.deadlocker8.budgetmaster.logic.NormalPayment; +import de.deadlocker8.budgetmasterserver.main.DatabaseHandler; +import de.deadlocker8.budgetmasterserver.main.DatabaseImporter; +import de.deadlocker8.budgetmasterserver.main.Settings; +import de.deadlocker8.budgetmasterserver.server.updater.RepeatingPaymentUpdater; +import logger.Logger; +import spark.Request; +import spark.Response; +import spark.Route; + +public class DatabaseImport implements Route +{ + private DatabaseHandler handler; + private Settings settings; + + public DatabaseImport(DatabaseHandler handler, Settings settings) + { + this.handler = handler; + this.settings = settings; + } + + @Override + public Object handle(Request req, Response res) throws Exception + { + if(!req.queryParams().contains("delete")) + { + halt(400, "Bad Request"); + } + //TODO json input? + + try + { + boolean delete = Boolean.parseBoolean(req.queryMap("delete").value()); +//TODO +// try +// { +// if(delete) +// { +// handler.deleteDatabase(); +// handler = new DatabaseHandler(settings); +// } +// +// DatabaseImporter importer = new DatabaseImporter(settings); +// importer.importDatabase(); +// return ""; +// } +// catch(Exception e) +// { +// Logger.error(e); +// halt(500, "Internal Server Error"); +// } + } + catch(Exception e) + { + halt(400, "Bad Request"); + } + + return null; + } +} \ No newline at end of file