Persoenliche Mediazentrale
ulrich
2021-04-07 3271f1608e851dedec0e53090af8ebd81c02b6b1
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;
21 import com.sun.net.httpserver.HttpExchange;
22 import com.sun.net.httpserver.HttpHandler;
23 import de.uhilger.mediaz.App;
f45e20 24 import static de.uhilger.mediaz.App.RB_EP_LISTE;
b379f5 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 /**
2597cd 40  * HttpHandler fuer die Verwaltung von Entitaeten der Mediazentrale
5f70da 41  * 
U 42  * @author Ulrich Hilger
43  * @version 1, 5.4.2021
b379f5 44  */
86bbf7 45 public class StorageHandler extends AbstractHandler 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/
f45e20 62     liefert alle Ablageort-Objekte
U 63   
64     HTTP GET an /mz/api/store/Ablageort/liste/  
2b5c60 65     liefert eine Liste der Namen vorhandener Ablageorte
b379f5 66   
U 67     HTTP GET an /mz/api/store/Ablageort/Katalog
68     liest den Ablageort namens "Katalog"
69   
70     HTTP POST an /mz/api/store/Ablageort
081606 71     schreibt den neuen Ablageort im Body der Anfrage (Neu)
b379f5 72   
U 73     HTTP PUT an /mz/api/store/Ablageort
74     sucht den Ablageort mit dem Namen laut Body der Anfrage 
081606 75     und schreibt den Inhalt aus der Anfrage in die Datei (Aenderung)
b379f5 76   
U 77     HTTP DELETE an /mz/api/store/Ablageort/Katalog
78     löscht den Ablageort namens "Katalog"
79   
80   */
81   
2b5c60 82   /** Name der HTTP Methode GET */
b379f5 83   public static final String HTTP_GET = "GET";
2b5c60 84   
U 85   /** Name der HTTP Methode PUT */
b379f5 86   public static final String HTTP_PUT = "PUT";
2b5c60 87   
U 88   /** Name der HTTP Methode POST */
b379f5 89   public static final String HTTP_POST = "POST";
2b5c60 90   
U 91   /** Name der HTTP Methode DELETE */
b379f5 92   public static final String HTTP_DELETE = "DELETE";
f45e20 93   
U 94   public static final String EP_LISTE = "liste/";
b379f5 95
U 96   @Override
97   public void handle(HttpExchange e) throws IOException {
98     String method = e.getRequestMethod();
5f70da 99     String response = "";
U 100     int code = 200;
b379f5 101     switch(method) {
U 102       case HTTP_GET:
5f70da 103         String json = lesen(e);
U 104         if(json != null) {
105           response = json;
106         } else {
107           response = "nicht gefunden";
108           code = 404;
109         }
b379f5 110         break;
U 111         
112       case HTTP_PUT:
2b5c60 113         response = aendern(e);
b379f5 114         break;
U 115         
116       case HTTP_POST:
5f70da 117         response = neu(e);
b379f5 118         break;
U 119         
120       case HTTP_DELETE:
2b5c60 121         boolean geloescht = loeschen(e);
U 122         if(geloescht) {
123           response = "geloescht";
124         } else {
125           response = "nicht geloescht";
126         }
b379f5 127         break;
U 128     }
b29119 129     logger.fine(response);
5f70da 130     e.sendResponseHeaders(code, response.length());
b379f5 131     OutputStream os = e.getResponseBody();
U 132     os.write(response.getBytes());
133     os.close();        
b1bf96 134   }
U 135   
5f70da 136   private String neu(HttpExchange e) throws IOException {
2597cd 137     return schreiben(e, false);
U 138   }
139   
140   private String aendern(HttpExchange e) throws IOException {
141     return schreiben(e, true);
142   }
143   
144   private String schreiben(HttpExchange e, boolean overwrite) throws IOException {
b1bf96 145     String path = e.getRequestURI().toString();
U 146     String[] elems = path.split(App.getRs(Server.RB_SLASH));
147     String type = elems[elems.length - 1];
148     String body = bodyLesen(e);
5f70da 149     String filename = ""; 
b1bf96 150     FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF)));
U 151     Gson gson = new Gson();
cf6509 152     logger.log(Level.FINE, "type: {0}, token: {1}", new Object[]{type, fs.typeFromName(type).getType().getTypeName()});
b1bf96 153     Object o = gson.fromJson(body, fs.typeFromName(type).getType());
U 154     if(o instanceof Entity) {
2597cd 155       Object antwortObjekt = fs.write((Entity) o, overwrite);
b1bf96 156       if(antwortObjekt instanceof File) {
U 157         File file = (File) antwortObjekt;
b29119 158         logger.log(Level.FINE, "Datei {0} geschrieben.", file.getAbsolutePath());
5f70da 159         filename = file.getName();
2597cd 160         return type + FileHandler.STR_BLANK + filename;
b1bf96 161       }
U 162     }
2597cd 163     return type + FileHandler.STR_BLANK + " Operation 'neu' fuer bereits existierende Entitaet.";
b1bf96 164   }
U 165   
2597cd 166   /*
2b5c60 167   private String aendern(HttpExchange e) throws IOException {
U 168     return neu(e); // einstweilen wird einfach ueberschrieben
b1bf96 169   }
2597cd 170   */
b1bf96 171   
2b5c60 172   private boolean loeschen(HttpExchange e) {
5f70da 173     String path = e.getRequestURI().toString();
U 174     String[] elems = path.split(App.getRs(Server.RB_SLASH));
175     String type = elems[elems.length - 2];
176     String elemName = elems[elems.length - 1];
177     FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF)));
2b5c60 178     return fs.delete(type, elemName);
U 179   }
180   
181   private String lesen(HttpExchange e) {
182     String path = e.getRequestURI().toString();
183     String[] elems = path.split(App.getRs(Server.RB_SLASH));
184     FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF)));
185     if(path.endsWith(App.getRs(RB_SLASH))) {
f45e20 186       List list = null;
U 187       if(path.endsWith(App.getRs(RB_EP_LISTE))) {
188         String type = elems[elems.length - 2];
189         logger.fine(type);
190         list = fs.list(type);
191       } else {
192         String type = elems[elems.length - 1];
193         logger.fine(type);
194         list = fs.listObjects(type);
195       }
a43e1a 196       return jsonWithEnclosingType(list);
2b5c60 197     } else {
U 198       String type = elems[elems.length - 2];
199       String elemName = elems[elems.length - 1];
200       return fs.readJson(type, elemName);
201     }
a43e1a 202   }
b379f5 203   
U 204   private String bodyLesen(HttpExchange e) throws IOException {
205     InputStream is = e.getRequestBody();
206     BufferedReader r = new BufferedReader(new InputStreamReader(is));
207     StringBuilder sb = new StringBuilder();
208     String line = r.readLine();
209     while(line != null) {
210       sb.append(line);
211       line = r.readLine();
212     }
213     r.close();
214     String json = sb.toString();
b29119 215     logger.log(Level.FINE, "json: {0}", json);
b379f5 216     return json;
U 217   }
218 }