package com.aemreunal.helper; /* * *********************** * * Copyright (c) 2015 * * * * This code belongs to: * * * * @author Ahmet Emre Ünal * * S001974 * * * * aemreunal@gmail.com * * emre.unal@ozu.edu.tr * * * * aemreunal.com * * *********************** * */ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.util.UUID; import org.springframework.web.multipart.MultipartFile; import com.aemreunal.config.GlobalSettings; import com.aemreunal.exception.textStorage.TextDeleteException; import com.aemreunal.exception.textStorage.TextLoadException; import com.aemreunal.exception.textStorage.TextSaveException; public class TextStorage { /** * Saves the given text to the filesystem and returns the name of the saved text file * as a {@link String}. * <p> * The method saves texts under the home folder of the user, inside the:<pre> * ~/{@value com.aemreunal.config.GlobalSettings#ROOT_STORAGE_FOLDER_DIRECTORY_NAME}/{@value * com.aemreunal.config.GlobalSettings#TEXT_STORAGE_FOLDER_DIRECTORY_NAME}/</pre> * folder. The texts will be put in a sub-folder structure like:<pre> * <user name>/<project ID>/<region ID>/<beacon ID>/</pre> * under the main storage folder. * <p> * If any of the folders above do not exist, they will be created. * * @param projectId * The ID of the project which the region (the text belongs to) is a part of. * @param regionId * The ID of the region (the beacon belongs to) of the text. * @param beaconId * The ID of the beacon of the text. * @param locationInfoTextFile * The text as a {@link MultipartFile}. * * @return The name of the saved text file as a {@link String}. * * @throws TextSaveException * If the text file can't be saved. */ public String saveText(Long projectId, Long regionId, Long beaconId, MultipartFile locationInfoTextFile) throws TextSaveException { // Get the file path from the project ID, and region ID attributes String filePath = getFilePath(projectId, regionId, beaconId); // Ensure unique file name File textFile = getUniqueFile(filePath); // Check for the existence of the parent folder and create it // if it doesn't exist createParentFolder(projectId, regionId, beaconId, textFile); // Create the new text file createFile(projectId, regionId, beaconId, textFile); // Write the text bytes to the new file writeTextToFile(projectId, regionId, beaconId, locationInfoTextFile, textFile); // Read the text properties to get dimensions return textFile.getName(); } /** * Loads the specified text file and returns the contents of the text file as a {@link * String}. * * @param projectId * The ID of the project which the region (the text belongs to) is a part of. * @param regionId * The ID of the region (the beacon belongs to) of the text. * @param beaconId * The ID of the beacon of the text. * @param textFileName * The name of the text file to be loaded. * * @return The contents of the text file as a {@link String} if the file has been * successfully loaded and read, an empty {@link String} otherwise. * * @throws TextLoadException * If the text file can't be loaded or read. */ public String loadText(Long projectId, Long regionId, Long beaconId, String textFileName) throws TextLoadException { // Get the file path from the project ID, region ID, and beacon ID attributes String filePath = getFilePath(projectId, regionId, beaconId); // Get the text file File textFile = new File(filePath + textFileName); if (!textFile.exists()) { System.err.println("Text file does not exist!"); throw new TextLoadException(projectId, regionId, beaconId); } return loadTextFromFile(projectId, regionId, beaconId, textFile); } /** * Deletes the specified text file. The method will do nothing if a {@code null} value * or empty string is provided for the {@code textFileName} parameter. * * @param projectId * The ID of the project which the region (the beacon belongs to) is a part * of. * @param regionId * The ID of the region of the beacon. * @param beaconId * The ID of the beacon of the text. * @param textFileName * The name of the text file to be deleted. If a {@code null} value or an * empty string is provided, the method will do nothing and return. * * @throws TextDeleteException * If the text file can't be deleted. */ public void deleteText(Long projectId, Long regionId, Long beaconId, String textFileName) throws TextDeleteException { if (textFileName == null || textFileName.equals("")) { return; } // Get the file path from the username, project ID, region ID, and beacon ID attributes String filePath = getFilePath(projectId, regionId, beaconId); // Get the text file File textFile = new File(filePath + textFileName); try { Files.delete(textFile.toPath()); } catch (NoSuchFileException e) { GlobalSettings.err("WARNING: Text file for project: " + projectId + ", region: " + regionId + ", beacon: " + beaconId + ", file name: " + textFileName + " does not exist, nothing to delete!"); } catch (IOException e) { GlobalSettings.err("Unable to delete the text!"); throw new TextDeleteException(projectId, regionId, beaconId); } } private String getFilePath(Long projectId, Long regionId, Long beaconId) { return GlobalSettings.TEXT_STORAGE_FOLDER_PATH + "/" + projectId + "/" + regionId + "/" + beaconId + "/"; } private File getUniqueFile(String filePath) { File textFile; do { String fileName = UUID.randomUUID().toString(); textFile = new File(filePath + fileName); } while (textFile.exists()); return textFile; } private void createParentFolder(Long projectId, Long regionId, Long beaconId, File textFile) throws TextSaveException { if (!textFile.getParentFile().exists()) { // If it doesn't exist, create it if (!textFile.getParentFile().mkdirs()) { System.err.println("Unable to create parent folders!"); throw new TextSaveException(projectId, regionId, beaconId); } } } private void createFile(Long projectId, Long regionId, Long beaconId, File textFile) throws TextSaveException { try { if (!textFile.createNewFile()) { System.err.println("Unable to createNewFile()!"); throw new TextSaveException(projectId, regionId, beaconId); } } catch (IOException e) { System.err.println("Unable to create file!"); throw new TextSaveException(projectId, regionId, beaconId); } } private String loadTextFromFile(Long projectId, Long regionId, Long beaconId, File textFile) throws TextLoadException { StringBuilder builder = new StringBuilder(); try { Files.readAllLines(textFile.toPath()).forEach(builder::append); } catch (FileNotFoundException e) { System.err.println("File to read from is not found!"); throw new TextLoadException(projectId, regionId, beaconId); } catch (IOException e) { System.err.println("Unable to read from file!"); throw new TextLoadException(projectId, regionId, beaconId); } return builder.toString(); } private void writeTextToFile(Long projectId, Long regionId, Long beaconId, MultipartFile locationInfoMultipartFile, File textFile) throws TextSaveException { try { locationInfoMultipartFile.transferTo(textFile); } catch (IOException e) { System.err.println("Unable to write text to file!"); throw new TextSaveException(projectId, regionId, beaconId); } } }