Persoenliche Mediazentrale
ulrich
2021-04-08 0a58e2c709547269ddbe4b2d92601521667cd765
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;
U 30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.InputStreamReader;
33 import java.io.OutputStream;
2b5c60 34 import java.util.List;
081606 35 import java.util.logging.Level;
b379f5 36 import java.util.logging.Logger;
U 37
38 /**
2597cd 39  * HttpHandler fuer die Verwaltung von Entitaeten der Mediazentrale
5f70da 40  * 
U 41  * @author Ulrich Hilger
42  * @version 1, 5.4.2021
b379f5 43  */
86bbf7 44 public class StorageHandler extends AbstractHandler implements HttpHandler {
b379f5 45   
081606 46   private static final Logger logger = Logger.getLogger(StorageHandler.class.getName());
b379f5 47
U 48   
0a58e2 49   /*  
U 50     Das REST-Muster fuer die Mediazentrale (Beispiel Ablageort):
2b5c60 51     
0a58e2 52     1. HTTP GET Ablageort/[Name]  - Liefere den Ablageort namens [Name]
dfb7d3 53     2. HTTP GET Ablageort/liste/  - Liefere eine Liste mit Namen aller Ablageorte
0a58e2 54                                      Es duerfen keine Elemente namens "liste" angelegt werden
dfb7d3 55     3. HTTP GET Ablageort/        - Liefere eine Liste aller Ablageort-Objekte als JSON
0a58e2 56     4. HTTP PUT Ablageort/[Name]  - Der Ablageort wird angelegt. Wenn er bereits existiert, 
U 57                                       wird er geändert. (im Falle einer Aenderung des Namens
58                                       muss der alte Name im URL stehen und im Body die Aenderung)
dfb7d3 59     5. HTTP DELETE                - loesche den Ablageort
b379f5 60   
U 61     Beispiele:
2b5c60 62   
0a58e2 63     HTTP GET /mz/api/store/Ablageort/
f45e20 64     liefert alle Ablageort-Objekte
U 65   
0a58e2 66     HTTP GET /mz/api/store/Ablageort/liste/  
2b5c60 67     liefert eine Liste der Namen vorhandener Ablageorte
b379f5 68   
0a58e2 69     HTTP GET /mz/api/store/Ablageort/[Name]
dfb7d3 70     liest den Ablageort namens [Name]
b379f5 71   
0a58e2 72     HTTP PUT /mz/api/store/Ablageort/[Name]
dfb7d3 73     wenn [Name] existiert: Aenderung, sonst neu anlegen
b379f5 74   
0a58e2 75     HTTP DELETE /mz/api/store/Ablageort/[Name]
dfb7d3 76     löscht den Ablageort namens [Name]
b379f5 77   
U 78   */
79   
2b5c60 80   /** Name der HTTP Methode GET */
b379f5 81   public static final String HTTP_GET = "GET";
2b5c60 82   
U 83   /** Name der HTTP Methode PUT */
b379f5 84   public static final String HTTP_PUT = "PUT";
2b5c60 85   
U 86   /** Name der HTTP Methode POST */
b379f5 87   public static final String HTTP_POST = "POST";
2b5c60 88   
U 89   /** Name der HTTP Methode DELETE */
b379f5 90   public static final String HTTP_DELETE = "DELETE";
f45e20 91   
U 92   public static final String EP_LISTE = "liste/";
b379f5 93
U 94   @Override
95   public void handle(HttpExchange e) throws IOException {
96     String method = e.getRequestMethod();
5f70da 97     String response = "";
U 98     int code = 200;
b379f5 99     switch(method) {
U 100       case HTTP_GET:
5f70da 101         String json = lesen(e);
U 102         if(json != null) {
103           response = json;
104         } else {
105           response = "nicht gefunden";
106           code = 404;
107         }
b379f5 108         break;
U 109         
110       case HTTP_PUT:
dfb7d3 111         response = put(e);
b379f5 112         break;
U 113         
114       case HTTP_POST:
dfb7d3 115         response = "nicht unterstuertzt.";
U 116         code = 404;
b379f5 117         break;
U 118         
119       case HTTP_DELETE:
2b5c60 120         boolean geloescht = loeschen(e);
U 121         if(geloescht) {
122           response = "geloescht";
123         } else {
124           response = "nicht geloescht";
125         }
b379f5 126         break;
U 127     }
b29119 128     logger.fine(response);
5f70da 129     e.sendResponseHeaders(code, response.length());
b379f5 130     OutputStream os = e.getResponseBody();
U 131     os.write(response.getBytes());
132     os.close();        
b1bf96 133   }
U 134   
dfb7d3 135   private String put(HttpExchange e) throws IOException {
U 136     String path = e.getRequestURI().toString();
137     String[] elems = path.split(App.getRs(Server.RB_SLASH));
138     String type = elems[elems.length - 2];
139     String elemName = elems[elems.length - 1]; // alter Name, wenn Aenderung
140     if(!elemName.equalsIgnoreCase(App.getRs(RB_EP_LISTE))) {
141       FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF)));
142       Gson gson = new Gson();
143       logger.log(Level.FINE, "type: {0}, token: {1}", new Object[]{type, fs.typeFromName(type).getType().getTypeName()});
144       Object o = gson.fromJson(bodyLesen(e), fs.typeFromName(type).getType());
145       if(o instanceof Entity) {
146         Entity entity = (Entity) o;
147         if(fs.exists(type, elemName)) {
148           fs.delete(type, elemName);
149           fs.write(entity, true);
150         } else {
151           fs.write(entity, false);
152         }
153         return type + App.getRs(Server.RB_SLASH) + entity.getName();
154       } else {
155         return "Ungueltiges Objekt im Body.";
156       }
157     } else {
158       return "Ungueltiger Elementname: " + App.getRs(RB_EP_LISTE);
159     }
160   }
2b5c60 161   private boolean loeschen(HttpExchange e) {
5f70da 162     String path = e.getRequestURI().toString();
U 163     String[] elems = path.split(App.getRs(Server.RB_SLASH));
164     String type = elems[elems.length - 2];
165     String elemName = elems[elems.length - 1];
166     FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF)));
2b5c60 167     return fs.delete(type, elemName);
U 168   }
169   
170   private String lesen(HttpExchange e) {
171     String path = e.getRequestURI().toString();
172     String[] elems = path.split(App.getRs(Server.RB_SLASH));
173     FileStorage fs = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF)));
174     if(path.endsWith(App.getRs(RB_SLASH))) {
f45e20 175       List list = null;
dfb7d3 176       if(elems[elems.length - 1].equalsIgnoreCase(App.getRs(RB_EP_LISTE))) {
f45e20 177         String type = elems[elems.length - 2];
U 178         logger.fine(type);
179         list = fs.list(type);
180       } else {
181         String type = elems[elems.length - 1];
182         logger.fine(type);
183         list = fs.listObjects(type);
184       }
a43e1a 185       return jsonWithEnclosingType(list);
2b5c60 186     } else {
U 187       String type = elems[elems.length - 2];
188       String elemName = elems[elems.length - 1];
189       return fs.readJson(type, elemName);
190     }
a43e1a 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();
b29119 204     logger.log(Level.FINE, "json: {0}", json);
b379f5 205     return json;
U 206   }
207 }