/* Mediazentrale - Personal Media Center Copyright (C) 2021 Ulrich Hilger This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package de.uhilger.mediaz.store; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import de.uhilger.mediaz.App; import de.uhilger.mediaz.Server; import de.uhilger.mediaz.entity.Ablageort; import de.uhilger.mediaz.entity.Abspieler; import de.uhilger.mediaz.entity.Abspielliste; import de.uhilger.mediaz.entity.Einstellung; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.logging.Logger; import de.uhilger.mediaz.entity.Entity; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; /** * Ablage fuer Dateien der Mediazentrale * * [Basispfad]/[Typ]/[Name] * * Typ ist eine der Klassen der Package entity * Name muss identisch mit dem Element laut Entity.getName() sein * * @author ulrich * @version 1, 5.4.2021 */ public class FileStorage implements Storage { private static final Logger logger = Logger.getLogger(FileStorage.class.getName()); /** StorageType Ablageort */ public static final String ST_ABLAGEORT = "Ablageort"; public static final String ST_EINSTELLUNG = "Einstellung"; public static final String ST_ABSPIELER = "Abspieler"; private final String fileBase; private final Map types; public FileStorage(String base) { this.fileBase = base; // Beispiel: TypeToken> list = new TypeToken>() {}; TypeToken ttAblageort = new TypeToken() {}; TypeToken ttEinstellung = new TypeToken() {}; TypeToken ttAbspieler = new TypeToken() {}; TypeToken ttAbspielliste = new TypeToken() {}; types = new HashMap(); types.put(Ablageort.class.getSimpleName(), ttAblageort); types.put(Einstellung.class.getSimpleName(), ttEinstellung); types.put(Abspieler.class.getSimpleName(), ttAbspieler); types.put(Abspielliste.class.getSimpleName(), ttAbspielliste); } /** * Ein Objekt als JSON in eine Datei schreiben * * Es wird in den Ordner geschrieben, der von conf angegeben ist * * Wenn es z.B.ein Ablage-Objekt ist, wird das Objekt in die Datei [conf]/Ablage/[name der Ablage].json geschrieben Der Name der Ablage muss eindeutig sein * * * @param entity das Objekt, das geschrieben werden soll * @param overwrite true, wenn Aenderung, false fuer neue Elemente * @return die Datei oder null, wenn die Datei existiert und ein * neues Element (overwrite=false) uebergeben wurde * @throws java.io.IOException */ public File writeToFile(Entity entity, boolean overwrite) throws IOException { String className = entity.getClass().getSimpleName(); logger.finer(className); File dir = new File(fileBase, className); dir.mkdirs(); File file = new File(dir, entity.getName()); if(file.exists() && !overwrite) { return null; } else { FileWriter fw = new FileWriter(file); Gson gson = new Gson(); fw.write(gson.toJson(entity)); fw.flush(); fw.close(); return file; } } public String readFromFile(File file) throws IOException { StringBuilder sb = new StringBuilder(); BufferedReader r = new BufferedReader(new FileReader(file)); String line = r.readLine(); while(line != null) { sb.append(line); line = r.readLine(); } r.close(); return sb.toString(); } public Entity entityFromFile(File file) throws ClassNotFoundException, FileNotFoundException, IOException { String json = readFromFile(file); Gson gson = new Gson(); return gson.fromJson(json, typeFromName(typeNameFromPath(file)).getType()); } private String typeNameFromPath(File file) { String[] parts = file.getPath().split(App.getRs(Server.RB_SLASH)); return parts[parts.length-2]; } @Override public Object write(Entity e, boolean overwrite) { try { return writeToFile(e, overwrite); } catch (IOException ex) { logger.log(Level.SEVERE, null, ex); return null; } } @Override public Entity read(String typ, String name) { try { return entityFromFile(getFile(typ, name)); } catch (ClassNotFoundException | IOException ex) { logger.log(Level.SEVERE, null, ex); return null; } } @Override public List list(String typ) { File base = new File(fileBase); File dir = new File(base, typ); List list = new ArrayList(); File[] files = dir.listFiles(); if(files != null) { for(File file : files) { //NamedItem n = new NamedItem(); //n.setLabel(file.getName()); list.add(file.getName()); } } return list; } @Override public TypeToken typeFromName(String name) { return types.get(name); } @Override public String readJson(String typ, String name) { try { return readFromFile(getFile(typ, name)); } catch (IOException ex) { logger.log(Level.SEVERE, null, ex); return null; } } private File getFile(String typ, String name) { File base = new File(fileBase); File dir = new File(base, typ); return new File(dir, name); } @Override public boolean delete(String typ, String name) { File file = getFile(typ, name); if(file.exists()) { return file.delete(); } else { return false; } } @Override public List listObjects(String typ) { File base = new File(fileBase); File dir = new File(base, typ); List list = new ArrayList(); File[] files = dir.listFiles(); if(files != null) { for(File file : files) { try { list.add(entityFromFile(file)); } catch (ClassNotFoundException | IOException ex) { logger.log(Level.SEVERE, null, ex); } } } return list; } public boolean exists(String typ, String name) { return getFile(typ, name).exists(); } }