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.CategoryTypeAdapter;

Karsch Lukas
committed
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();
}
Path toCategoryJson = Path.of(userPath + "/categories.json");
if (Files.exists(toCategoryJson) && Files.isRegularFile(toCategoryJson)) {
categoryManager = deserializeCategoryManager(toCategoryJson);
} else {
categoryManager = new CategoryManager();
}

Karsch Lukas
committed
return null;
}

Karsch Lukas
committed
}

Karsch Lukas
committed
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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(Path path) {
Gson gson = new GsonBuilder().registerTypeAdapter(Category.class, new CategoryTypeAdapter()).create();

Karsch Lukas
committed
return null;
}

Karsch Lukas
committed
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
145
146
147
148
149
150
151
152
153
154
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();