From 61238c44b3ce821d81258f9b13dde2afe622e8d0 Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Mon, 30 Jul 2018 12:12:50 +0200
Subject: [PATCH] #259 - improved import error handling

---
 .../controller/SettingsController.java        | 10 +++--
 .../budgetmaster/database/DatabaseParser.java | 43 +++++++++++--------
 .../database/DatabaseParser_v3.java           |  1 -
 src/main/resources/languages/_de.properties   |  6 +++
 src/main/resources/languages/_en.properties   |  6 +++
 src/main/resources/templates/settings.ftl     | 12 ++++++
 6 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/src/main/java/de/deadlocker8/budgetmaster/controller/SettingsController.java b/src/main/java/de/deadlocker8/budgetmaster/controller/SettingsController.java
index 86cc46e29..76d257470 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/controller/SettingsController.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/controller/SettingsController.java
@@ -5,6 +5,7 @@ import de.deadlocker8.budgetmaster.authentication.UserRepository;
 import de.deadlocker8.budgetmaster.database.Database;
 import de.deadlocker8.budgetmaster.database.DatabaseParser;
 import de.deadlocker8.budgetmaster.entities.Settings;
+import de.deadlocker8.budgetmaster.repositories.AccountRepository;
 import de.deadlocker8.budgetmaster.repositories.SettingsRepository;
 import de.deadlocker8.budgetmaster.services.DatabaseService;
 import de.deadlocker8.budgetmaster.services.HelpersService;
@@ -48,6 +49,9 @@ public class SettingsController extends BaseController
 	@Autowired
 	private DatabaseService databaseService;
 
+	@Autowired
+	private AccountRepository accountRepository;
+
 	@RequestMapping("/settings")
 	public String settings(Model model)
 	{
@@ -187,7 +191,7 @@ public class SettingsController extends BaseController
 	}
 
 	@RequestMapping("/settings/database/upload")
-	public String upload(@RequestParam("file") MultipartFile file)
+	public String upload(Model model, @RequestParam("file") MultipartFile file)
 	{
 		if(file.isEmpty())
 		{
@@ -199,12 +203,12 @@ public class SettingsController extends BaseController
 			String jsonString = new String(file.getBytes());
 			DatabaseParser importer = new DatabaseParser(jsonString);
 			Database database = importer.parseDatabaseFromJSON();
-
 		}
 		catch(Exception e)
 		{
-			//TODO
 			e.printStackTrace();
+			model.addAttribute("errorImportDatabase", e.getMessage());
+			return "settings";
 		}
 
 		//TODO redirect to account combination page
diff --git a/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser.java b/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser.java
index 9577f5302..a4676a386 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser.java
@@ -2,9 +2,11 @@ package de.deadlocker8.budgetmaster.database;
 
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
+import com.google.gson.stream.MalformedJsonException;
 import de.deadlocker8.budgetmaster.database.legacy.LegacyParser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import tools.Localization;
 
 public class DatabaseParser
 {
@@ -18,26 +20,33 @@ public class DatabaseParser
 
 	public Database parseDatabaseFromJSON() throws IllegalArgumentException
 	{
-		JsonObject root = new JsonParser().parse(jsonString).getAsJsonObject();
-		String type = root.get("TYPE").getAsString();
-		if(!type.equals(JSONIdentifier.BUDGETMASTER_DATABASE.toString()))
+		try
 		{
-			throw new IllegalArgumentException("JSON is not of type BUDGETMASTER_DATABASE");
+			JsonObject root = new JsonParser().parse(jsonString).getAsJsonObject();
+			String type = root.get("TYPE").getAsString();
+			if(!type.equals(JSONIdentifier.BUDGETMASTER_DATABASE.toString()))
+			{
+				throw new IllegalArgumentException("JSON is not of type BUDGETMASTER_DATABASE");
+			}
+
+			int version = root.get("VERSION").getAsInt();
+			LOGGER.info("Parsing Budgetmaster database with version " + version);
+
+			if(version == 2)
+			{
+				return new LegacyParser(jsonString).parseDatabaseFromJSON();
+			}
+
+			if(version == 3)
+			{
+				return new DatabaseParser_v3(jsonString).parseDatabaseFromJSON();
+			}
+
+			throw new IllegalArgumentException(Localization.getString("error.database.import.unknown.version"));
 		}
-
-		int version = root.get("VERSION").getAsInt();
-		LOGGER.info("Parsing Budgetmaster database with version " + version);
-
-		if(version == 2)
-		{
-			return new LegacyParser(jsonString).parseDatabaseFromJSON();
-		}
-
-		if(version == 3)
+		catch(Exception e)
 		{
-			return new DatabaseParser_v3(jsonString).parseDatabaseFromJSON();
+			throw new IllegalArgumentException(Localization.getString("error.database.import.invalid.json"));
 		}
-
-		throw new IllegalArgumentException("unknown BUDGETMASTER_DATABASE version");
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser_v3.java b/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser_v3.java
index 105604c65..b50348f6d 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser_v3.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/database/DatabaseParser_v3.java
@@ -21,7 +21,6 @@ public class DatabaseParser_v3
 	private List<Category> categories;
 	private List<Account> accounts;
 
-
 	public DatabaseParser_v3(String json)
 	{
 		this.jsonString = json;
diff --git a/src/main/resources/languages/_de.properties b/src/main/resources/languages/_de.properties
index 89c2507c7..a636b3f4e 100644
--- a/src/main/resources/languages/_de.properties
+++ b/src/main/resources/languages/_de.properties
@@ -17,6 +17,11 @@ errorpages.418=I'm a teapot.
 errorpages.418.credits=Teapot icon made by <a href="http://www.freepik.com" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
 errorpages.500=Ein interner Serverfehler ist aufgetreten.
 
+error.title.database.import=Importfehler
+error.text.database.import=Beim Importieren der Datei ist ein Fehler aufgetreten.<br>Details:<br>{0}
+error.database.import.invalid.json=Die hochgeladene JSON Datei ist ung�ltig.
+error.database.import.unknown.version=Die hochgeladene JSON Datei enth�lt keine g�ltige Definition einerBudgetMaster Datenbank.
+
 # TITLE
 title.incomes=Einnahmen
 title.income=Einnahme
@@ -81,6 +86,7 @@ info.text.payment.delete=M
 info.title.database.delete=Datenbank l�schen
 info.header.text.database.delete=Soll die Datenbank wirklich unwiderruflich gel�scht werden?
 info.text.database.delete=Zur Best�tigung gib folgenden Code ein:\t{0}
+info.title.database.import.dialog=Datenbank importieren
 
 # WARNING
 warning.text.account.delete=Das Konto "{0}" kann nicht gel�scht werden, da mindestens ein Konto existieren muss. Um dieses Konto zu l�schen musst du zuerst ein neues anlegen.
diff --git a/src/main/resources/languages/_en.properties b/src/main/resources/languages/_en.properties
index 562d7aa3b..f61310a23 100644
--- a/src/main/resources/languages/_en.properties
+++ b/src/main/resources/languages/_en.properties
@@ -17,6 +17,11 @@ errorpages.418=I''m a teapot.
 errorpages.418.credits=Teapot icon made by <a href="http://www.freepik.com" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
 errorpages.500=An internal server error occurred.
 
+error.title.database.import=Import Error
+error.text.database.import=An error occurred while importing the file.<br>Details:<br>{0}
+error.database.import.invalid.json=The uploaded JSON File is invalid.
+error.database.import.unknown.version=The uploaded JSON File does not contain a valid BudgetMaster database definition.
+
 # TITLE
 title.incomes=Incomes
 title.income=Income
@@ -81,6 +86,7 @@ info.text.payment.delete=Do you really want to delete the entry "{0}"? This can'
 info.title.database.delete=Delete Database
 info.header.text.database.delete=Do you really want to delete the database? This can''t be undone.
 info.text.database.delete=Please enter the following code for verification:\t{0}
+info.title.database.import.dialog=Import database
 
 # WARNING
 warning.text.account.delete=The account "{0}" could not be deleted, because at least one account must exist at all time. You have to create a new account in order to delete this one.
diff --git a/src/main/resources/templates/settings.ftl b/src/main/resources/templates/settings.ftl
index ab1fa03ff..8ba7ee27d 100644
--- a/src/main/resources/templates/settings.ftl
+++ b/src/main/resources/templates/settings.ftl
@@ -229,6 +229,18 @@
             </div>
         </#if>
 
+        <#if errorImportDatabase??>
+            <div id="modalErrorImportDatabase" class="modal background-color">
+                <div class="modal-content">
+                    <h4>${locale.getString("error.title.database.import")}</h4>
+                    <p>${locale.getString("error.text.database.import", errorImportDatabase)}</p>
+                </div>
+                <div class="modal-footer background-color">
+                    <a href="/settings" class="modal-action modal-close waves-effect waves-red btn-flat ">${locale.getString("ok")}</a>
+                </div>
+            </div>
+        </#if>
+
         <!-- Scripts-->
         <#import "scripts.ftl" as scripts>
         <@scripts.scripts/>
-- 
GitLab