Persoenliche Mediazentrale
ulrich
2021-04-05 a43e1a055018aab9590c88c45d8495f99bfb6254
commit | author | age
b379f5 1 /*
5f70da 2   Mediazentrale - Personal Media Center
U 3   Copyright (C) 2021  Ulrich Hilger
4
5   This program is free software: you can redistribute it and/or modify
6   it under the terms of the GNU Affero General Public License as
7   published by the Free Software Foundation, either version 3 of the
8   License, or (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU Affero General Public License for more details.
14
15   You should have received a copy of the GNU Affero General Public License
16   along with this program.  If not, see <https://www.gnu.org/licenses/>.
b379f5 17  */
U 18 package de.uhilger.mediaz.api;
19
20 import com.google.gson.Gson;
a43e1a 21 import com.google.gson.GsonBuilder;
b379f5 22 import com.sun.net.httpserver.HttpExchange;
U 23 import com.sun.net.httpserver.HttpHandler;
24 import de.uhilger.mediaz.App;
25 import de.uhilger.mediaz.Server;
2b5c60 26 import static de.uhilger.mediaz.Server.RB_SLASH;
081606 27 import de.uhilger.mediaz.store.FileStorage;
b1bf96 28 import de.uhilger.mediaz.entity.Entity;
b379f5 29 import java.io.BufferedReader;
081606 30 import java.io.File;
b379f5 31 import java.io.IOException;
U 32 import java.io.InputStream;
33 import java.io.InputStreamReader;
34 import java.io.OutputStream;
2b5c60 35 import java.util.List;
081606 36 import java.util.logging.Level;
b379f5 37 import java.util.logging.Logger;
U 38
39 /**
5f70da 40  * HttpHandler fuer die Ablage von Entitaeten der Mediazentrale
U 41  * 
42  * @author Ulrich Hilger
43  * @version 1, 5.4.2021
b379f5 44  */
081606 45 public class StorageHandler implements HttpHandler  {
b379f5 46   
081606 47   private static final Logger logger = Logger.getLogger(StorageHandler.class.getName());
b379f5 48
U 49   
50   /*
2b5c60 51     Das REST-Muster sieht je Entitaet fuenf Faelle vor (Beispiel Ablageort):
U 52     
53     1. HTTP GET Ablageort/[Name]: Liefere den Ablageort als JSON
54     2. HTTP GET Ablageort/: Liefere einer Liste von Ablageorten als JSON
55     3. HTTP PUT: schreibe einen neuen Ablageort auf die Platte
56     4. HTTP POST: schreibe Aenderungen auf die Platte
57     5. HTTP DELETE: loesche den Ablageort
b379f5 58   
U 59     Beispiele:
2b5c60 60   
U 61     HTTP GET an /mz/api/store/Ablageort/
62     liefert eine Liste der Namen vorhandener Ablageorte
b379f5 63   
U 64     HTTP GET an /mz/api/store/Ablageort/Katalog
65     liest den Ablageort namens "Katalog"
66   
67     HTTP POST an /mz/api/store/Ablageort
081606 68     schreibt den neuen Ablageort im Body der Anfrage (Neu)
b379f5 69   
U 70     HTTP PUT an /mz/api/store/Ablageort
71     sucht den Ablageort mit dem Namen laut Body der Anfrage 
081606 72     und schreibt den Inhalt aus der Anfrage in die Datei (Aenderung)
b379f5 73   
U 74     HTTP DELETE an /mz/api/store/Ablageort/Katalog
75     löscht den Ablageort namens "Katalog"
76   
77   */
78   
2b5c60 79   /** Name der HTTP Methode GET */
b379f5 80   public static final String HTTP_GET = "GET";
2b5c60 81   
U 82   /** Name der HTTP Methode PUT */
b379f5 83   public static final String HTTP_PUT = "PUT";
2b5c60 84   
U 85   /** Name der HTTP Methode POST */
b379f5 86   public static final String HTTP_POST = "POST";
2b5c60 87   
U 88   /** Name der HTTP Methode DELETE */
b379f5 89   public static final String HTTP_DELETE = "DELETE";
U 90
91   @Override
92   public void handle(HttpExchange e) throws IOException {
93     String method = e.getRequestMethod();
5f70da 94     String response = "";
U 95     int code = 200;
b379f5 96     switch(method) {
U 97       case HTTP_GET:
5f70da 98         String json = lesen(e);
U 99         if(json != null) {
100           response = json;
101         } else {
102           response = "nicht gefunden";
103           code = 404;
104         }
b379f5 105         break;
U 106         
107       case HTTP_PUT:
2b5c60 108         response = aendern(e);
b379f5 109         break;
U 110         
111       case HTTP_POST:
5f70da 112         response = neu(e);
b379f5 113         break;
U 114         
115       case HTTP_DELETE:
2b5c60 116         boolean geloescht = loeschen(e);
U 117         if(geloescht) {
118           response = "geloescht";
119         } else {
120           response = "nicht geloescht";
121         }
b379f5 122         break;
U 123     }
124     logger.info(response);
5f70da 125     e.sendResponseHeaders(code, response.length());
b379f5 126     OutputStream os = e.getResponseBody();
U 127     os.write(response.getBytes());
128     os.close();        
b1bf96 129   }
U 130   
5f70da 131   private String neu(HttpExchange e) throws IOException {
b1bf96 132     String path = e.getRequestURI().toString();
U 133     String[] elems = path.split(App.getRs(Server.RB_SLASH));
134     String type = elems[elems.length - 1];
135     String body = bodyLesen(e);
5f70da 136     String filename = ""; 
b1bf96 137     FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF)));
U 138     Gson gson = new Gson();
139     logger.log(Level.INFO, "type: {0}", type);
140     Object o = gson.fromJson(body, fs.typeFromName(type).getType());
141     if(o instanceof Entity) {
142       Object antwortObjekt = fs.write((Entity) o);
143       if(antwortObjekt instanceof File) {
144         File file = (File) antwortObjekt;
145         logger.log(Level.INFO, "Datei {0} geschrieben.", file.getAbsolutePath());
5f70da 146         filename = file.getName();
b1bf96 147       }
U 148     }
5f70da 149     return type + FileHandler.STR_BLANK + filename;
b1bf96 150   }
U 151   
2b5c60 152   private String aendern(HttpExchange e) throws IOException {
U 153     return neu(e); // einstweilen wird einfach ueberschrieben
b1bf96 154   }
U 155   
2b5c60 156   private boolean loeschen(HttpExchange e) {
5f70da 157     String path = e.getRequestURI().toString();
U 158     String[] elems = path.split(App.getRs(Server.RB_SLASH));
159     String type = elems[elems.length - 2];
160     String elemName = elems[elems.length - 1];
161     FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF)));
2b5c60 162     return fs.delete(type, elemName);
U 163   }
164   
165   private String lesen(HttpExchange e) {
166     String path = e.getRequestURI().toString();
167     String[] elems = path.split(App.getRs(Server.RB_SLASH));
168     FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF)));
169     if(path.endsWith(App.getRs(RB_SLASH))) {
170       String type = elems[elems.length - 1];
171       logger.info(type);
172       List list = fs.list(type);
a43e1a 173       return jsonWithEnclosingType(list);
2b5c60 174     } else {
U 175       String type = elems[elems.length - 2];
176       String elemName = elems[elems.length - 1];
177       return fs.readJson(type, elemName);
178     }
b379f5 179   }
U 180   
a43e1a 181   private String jsonWithEnclosingType(Object o) {
U 182     StringBuilder sb = new StringBuilder();
183     sb.append("{\"");
184     sb.append(o.getClass().getSimpleName());
185     sb.append("\": ");
186     Gson gson = new Gson();
187     sb.append(gson.toJson(o));
188     sb.append("}");
189     return sb.toString();
190   }
191   
b379f5 192   
U 193   private String bodyLesen(HttpExchange e) throws IOException {
194     InputStream is = e.getRequestBody();
195     BufferedReader r = new BufferedReader(new InputStreamReader(is));
196     StringBuilder sb = new StringBuilder();
197     String line = r.readLine();
198     while(line != null) {
199       sb.append(line);
200       line = r.readLine();
201     }
202     r.close();
203     String json = sb.toString();
b1bf96 204     logger.log(Level.INFO, "json: {0}", json);
b379f5 205     return json;
U 206   }
207 }