Newer
Older

Karsch Lukas
committed
package mi.hdm.filesystem;

Karsch Lukas
committed
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

Karsch Lukas
committed
import mi.hdm.TastyPages;

Karsch Lukas
committed
import mi.hdm.mealPlan.MealPlan;
import mi.hdm.recipes.*;
import mi.hdm.shoppingList.ShoppingList;
import mi.hdm.typeAdapters.RecipeTypeAdapter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Karsch Lukas
committed

Karsch Lukas
committed
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
/**
* Containing methods to serialize and deserialize parts of the app content for saving to / loading from the filesystem
*/

Karsch Lukas
committed
public class FileManager {

Karsch Lukas
committed
private final static String PATH_TO_DEFAULT_INGREDIENTS = "/data/nutrition.csv";
private final static String PATH_TO_USER_DATA = System.getProperty("user.home") + "\\AppData\\Roaming\\TastyPages";
private final static Logger log = LogManager.getLogger(FileManager.class);
private final static Gson gson = new Gson();

Karsch Lukas
committed

Karsch Lukas
committed
public static void serializeToFile(TastyPages app) {

Karsch Lukas
committed
}

Karsch Lukas
committed
public static TastyPages deserializeFromFile() throws Exception { //TODO: if this fails, log.fatal and System.exit
log.info("Trying to read {}", PATH_TO_USER_DATA);
Path userPath = Path.of(PATH_TO_USER_DATA);
if (userPath.toFile().mkdirs()) { //If .mkdirs() returns true, that means the folder has not existed before -> in this case, only load default ingredients!
log.info("TastyPages folder has been created at {}", userPath);
IngredientManager deserializedIngredientManager = deserializeIngredientManager(getAbsolutePathFromResourceFolder(PATH_TO_DEFAULT_INGREDIENTS));
return new TastyPages(deserializedIngredientManager);
} else { //otherwise, read user data
log.info("Found TastyPages folder at {}, loading user data from there.", userPath);
IngredientManager ingredientManager;
RecipeManager recipeManager;
CategoryManager categoryManager;
MealPlan mealPlan;
ShoppingList shoppingList;
if (Files.exists(Path.of(userPath + "ingredients.csv"))) {
ingredientManager = deserializeIngredientManager(PATH_TO_USER_DATA);
} else {
ingredientManager = deserializeIngredientManager(getAbsolutePathFromResourceFolder(PATH_TO_DEFAULT_INGREDIENTS));
}
Path recipeFolder = Path.of(userPath + "/recipes");
if (Files.exists(recipeFolder) && Files.isDirectory(recipeFolder)) {
recipeManager = deserializeRecipeManager(PATH_TO_USER_DATA + "/recipes", ingredientManager);
} else {
recipeFolder.toFile().mkdir();
recipeManager = new RecipeManager();
}
return null;
}

Karsch Lukas
committed
}

Karsch Lukas
committed
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
private static IngredientManager deserializeIngredientManager(String path) throws IOException {
CSVParser parser = new CSVParser();
List<Ingredient> ingredients = parser.getIngredientsFromCSV(
path,
',',
"name", "calories", "carbohydrate", "fat", "protein", "fiber", "sodium"
);
return new IngredientManager(ingredients);
}
private static RecipeManager deserializeRecipeManager(String path, IngredientManager ingredientManager) throws Exception {
Path recipePath = Path.of(path);
List<Path> recipePaths;
try (Stream<Path> stream = Files.list(recipePath)) { //TODO: catch clause
recipePaths = stream.toList();
}
List<Recipe> recipes = recipePaths.stream()
.map(p -> {
try {
return Files.readString(p);
} catch (IOException e) {
e.printStackTrace();
log.error("Could not read file contents for {}. Check file permissions and content", p);
return "";
}
})
.map(FileManager::JSONtoRecipe)
.toList();
return new RecipeManager(recipes);
}
private static CategoryManager deserializeCategoryManager() {

Karsch Lukas
committed
return null;
}

Karsch Lukas
committed
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
private static MealPlan deserializeMealPlan() {
return null;
}
private static ShoppingList deserializeShoppingList() {
return null;
}
private static String recipeToJSON(Recipe recipe, IngredientManager ingredientManager) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Recipe.class, new RecipeTypeAdapter(ingredientManager))
.create();
return gson.toJson(recipe);
}
/**
* Used to convert an ingredient into a CSV String seperated by comma
*
* @return a comma seperated String containing the name of the ingredient as well as the contents of its nutrition table
*/
private static String ingredientToCSV(Ingredient ingredient) {
//"name", "calories", "carbohydrate", "fat", "protein", "fiber", "sodium"
Map<Nutrition, BigDecimal> map = ingredient.getNutritionTable().getTable();
return String.format(
"%s, %f, %f, %f, %f, %f, %f%n",
ingredient.getName(),
map.get(Nutrition.CALORIES).doubleValue(),
map.get(Nutrition.CARBS).doubleValue(),
map.get(Nutrition.FAT).doubleValue(),
map.get(Nutrition.PROTEINS).doubleValue(),
map.get(Nutrition.FIBERS).doubleValue(),
map.get(Nutrition.SALT).doubleValue()
);
}
private static Recipe JSONtoRecipe(String json) {
//when loading a recipe, is it important that its ingredients are the same objects as in the ingredient manager?
gson.fromJson(json, Recipe.class);
return null;

Karsch Lukas
committed
}

Karsch Lukas
committed
private static String getAbsolutePathFromResourceFolder(String resource) throws URISyntaxException {
URL resourceUrl = FileManager.class.getResource(resource);
assert resourceUrl != null;
Path path = Paths.get(resourceUrl.toURI());
return path.toFile().getAbsolutePath();