| | |
| | | /* |
| | | * To change this license header, choose License Headers in Project Properties. |
| | | * To change this template file, choose Tools | Templates |
| | | * and open the template in the editor. |
| | | 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 <https://www.gnu.org/licenses/>. |
| | | */ |
| | | package de.uhilger.mediaz.api; |
| | | |
| | |
| | | import com.sun.net.httpserver.HttpExchange; |
| | | import com.sun.net.httpserver.HttpHandler; |
| | | import de.uhilger.mediaz.App; |
| | | import static de.uhilger.mediaz.App.RB_EP_LISTE; |
| | | import de.uhilger.mediaz.Server; |
| | | import static de.uhilger.mediaz.Server.RB_SLASH; |
| | | import de.uhilger.mediaz.store.FileStorage; |
| | | import de.uhilger.mediaz.entity.Ablageort; |
| | | import de.uhilger.mediaz.entity.Entity; |
| | | import java.io.BufferedReader; |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.InputStreamReader; |
| | | import java.io.OutputStream; |
| | | import java.util.List; |
| | | import java.util.logging.Level; |
| | | import java.util.logging.Logger; |
| | | |
| | | /** |
| | | * |
| | | * @author ulrich |
| | | * HttpHandler fuer die Verwaltung von Entitaeten der Mediazentrale |
| | | * |
| | | * @author Ulrich Hilger |
| | | * @version 1, 5.4.2021 |
| | | */ |
| | | public class StorageHandler implements HttpHandler { |
| | | public class StorageHandler extends AbstractHandler implements HttpHandler { |
| | | |
| | | private static final Logger logger = Logger.getLogger(StorageHandler.class.getName()); |
| | | |
| | | |
| | | /* |
| | | |
| | | HTTP GET: lies einen Ablageort und schreibe JSON |
| | | HTTP PUT: schreibe einen neuen Ablageort auf die Platte |
| | | HTTP POST: schreibe Aenderungen auf die Platte |
| | | HTTP DELETE: loesche den Ablageort |
| | | Das REST-Muster sieht je Entitaet fuenf Faelle vor (Beispiel Ablageort): |
| | | |
| | | 1. HTTP GET Ablageort/[Name]: Liefere den Ablageort als JSON |
| | | 2. HTTP GET Ablageort/: Liefere einer Liste von Ablageorten als JSON |
| | | 3. HTTP PUT: schreibe einen neuen Ablageort auf die Platte |
| | | 4. HTTP POST: schreibe Aenderungen auf die Platte |
| | | 5. HTTP DELETE: loesche den Ablageort |
| | | |
| | | Beispiele: |
| | | |
| | | HTTP GET an /mz/api/store/Ablageort/ |
| | | liefert alle Ablageort-Objekte |
| | | |
| | | HTTP GET an /mz/api/store/Ablageort/liste/ |
| | | liefert eine Liste der Namen vorhandener Ablageorte |
| | | |
| | | HTTP GET an /mz/api/store/Ablageort/Katalog |
| | | liest den Ablageort namens "Katalog" |
| | |
| | | |
| | | */ |
| | | |
| | | /** Name der HTTP Methode GET */ |
| | | public static final String HTTP_GET = "GET"; |
| | | |
| | | /** Name der HTTP Methode PUT */ |
| | | public static final String HTTP_PUT = "PUT"; |
| | | |
| | | /** Name der HTTP Methode POST */ |
| | | public static final String HTTP_POST = "POST"; |
| | | |
| | | /** Name der HTTP Methode DELETE */ |
| | | public static final String HTTP_DELETE = "DELETE"; |
| | | |
| | | public static final String EP_LISTE = "liste/"; |
| | | |
| | | @Override |
| | | public void handle(HttpExchange e) throws IOException { |
| | | String method = e.getRequestMethod(); |
| | | String path = e.getRequestURI().toString(); |
| | | String[] elems = path.split(App.getRs(Server.RB_SLASH)); |
| | | String type = ""; |
| | | String elemName = ""; |
| | | FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF))); |
| | | String response = ""; |
| | | int code = 200; |
| | | switch(method) { |
| | | case HTTP_GET: |
| | | type = elems[elems.length - 2]; |
| | | elemName = elems[elems.length - 1]; |
| | | //this.readFromFile(file); |
| | | fs.read(type, elemName); |
| | | break; |
| | | |
| | | case HTTP_PUT: |
| | | type = elems[elems.length - 1]; |
| | | elemName = "noch bauen: lesen aus Body"; |
| | | break; |
| | | |
| | | case HTTP_POST: |
| | | type = elems[elems.length - 1]; |
| | | elemName = bodyLesen(e); |
| | | if(type.equalsIgnoreCase("Ablageort")) { |
| | | Gson gson = new Gson(); |
| | | Ablageort ort = gson.fromJson(elemName, Ablageort.class); |
| | | elemName = ort.getName(); |
| | | Object o = fs.write(ort); |
| | | if(o instanceof File) { |
| | | File file = (File) o; |
| | | logger.log(Level.INFO, "Datei {0} geschrieben.", file.getAbsolutePath()); |
| | | } |
| | | String json = lesen(e); |
| | | if(json != null) { |
| | | response = json; |
| | | } else { |
| | | response = "nicht gefunden"; |
| | | code = 404; |
| | | } |
| | | break; |
| | | |
| | | case HTTP_PUT: |
| | | response = aendern(e); |
| | | break; |
| | | |
| | | case HTTP_POST: |
| | | response = neu(e); |
| | | break; |
| | | |
| | | case HTTP_DELETE: |
| | | type = elems[elems.length - 2]; |
| | | elemName = elems[elems.length - 1]; |
| | | boolean geloescht = loeschen(e); |
| | | if(geloescht) { |
| | | response = "geloescht"; |
| | | } else { |
| | | response = "nicht geloescht"; |
| | | } |
| | | break; |
| | | } |
| | | |
| | | |
| | | String response = "Method: " + method + ", Path: " + path + |
| | | ", Type: " + type + ", elemName: " + elemName; |
| | | logger.info(response); |
| | | e.sendResponseHeaders(200, response.length()); |
| | | logger.fine(response); |
| | | e.sendResponseHeaders(code, response.length()); |
| | | OutputStream os = e.getResponseBody(); |
| | | os.write(response.getBytes()); |
| | | os.close(); |
| | | } |
| | | |
| | | private String neu(HttpExchange e) throws IOException { |
| | | return schreiben(e, false); |
| | | } |
| | | |
| | | private String aendern(HttpExchange e) throws IOException { |
| | | return schreiben(e, true); |
| | | } |
| | | |
| | | private String schreiben(HttpExchange e, boolean overwrite) throws IOException { |
| | | String path = e.getRequestURI().toString(); |
| | | String[] elems = path.split(App.getRs(Server.RB_SLASH)); |
| | | String type = elems[elems.length - 1]; |
| | | String body = bodyLesen(e); |
| | | String filename = ""; |
| | | FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF))); |
| | | Gson gson = new Gson(); |
| | | logger.log(Level.FINE, "type: {0}, token: {1}", new Object[]{type, fs.typeFromName(type).getType().getTypeName()}); |
| | | Object o = gson.fromJson(body, fs.typeFromName(type).getType()); |
| | | if(o instanceof Entity) { |
| | | Object antwortObjekt = fs.write((Entity) o, overwrite); |
| | | if(antwortObjekt instanceof File) { |
| | | File file = (File) antwortObjekt; |
| | | logger.log(Level.FINE, "Datei {0} geschrieben.", file.getAbsolutePath()); |
| | | filename = file.getName(); |
| | | return type + FileHandler.STR_BLANK + filename; |
| | | } |
| | | } |
| | | return type + FileHandler.STR_BLANK + " Operation 'neu' fuer bereits existierende Entitaet."; |
| | | } |
| | | |
| | | /* |
| | | private String aendern(HttpExchange e) throws IOException { |
| | | return neu(e); // einstweilen wird einfach ueberschrieben |
| | | } |
| | | */ |
| | | |
| | | private boolean loeschen(HttpExchange e) { |
| | | String path = e.getRequestURI().toString(); |
| | | String[] elems = path.split(App.getRs(Server.RB_SLASH)); |
| | | String type = elems[elems.length - 2]; |
| | | String elemName = elems[elems.length - 1]; |
| | | FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF))); |
| | | return fs.delete(type, elemName); |
| | | } |
| | | |
| | | private String lesen(HttpExchange e) { |
| | | String path = e.getRequestURI().toString(); |
| | | String[] elems = path.split(App.getRs(Server.RB_SLASH)); |
| | | FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF))); |
| | | if(path.endsWith(App.getRs(RB_SLASH))) { |
| | | List list = null; |
| | | if(path.endsWith(App.getRs(RB_EP_LISTE))) { |
| | | String type = elems[elems.length - 2]; |
| | | logger.fine(type); |
| | | list = fs.list(type); |
| | | } else { |
| | | String type = elems[elems.length - 1]; |
| | | logger.fine(type); |
| | | list = fs.listObjects(type); |
| | | } |
| | | return jsonWithEnclosingType(list); |
| | | } else { |
| | | String type = elems[elems.length - 2]; |
| | | String elemName = elems[elems.length - 1]; |
| | | return fs.readJson(type, elemName); |
| | | } |
| | | } |
| | | |
| | | private String bodyLesen(HttpExchange e) throws IOException { |
| | | InputStream is = e.getRequestBody(); |
| | |
| | | line = r.readLine(); |
| | | } |
| | | r.close(); |
| | | // {"Ablageort":{"name":"test1","ort":"test2","url":"test3"}} |
| | | //String data = sb.toString(); |
| | | //data = data.substring(1, data.length() - 1); |
| | | //String json = data.substring(data.indexOf("{")); |
| | | // {"name":"test1","ort":"test2","url":"test3"} |
| | | String json = sb.toString(); |
| | | logger.info("json: " + json); |
| | | logger.log(Level.FINE, "json: {0}", json); |
| | | return json; |
| | | } |
| | | } |