From dfb7d34f88efbb3eb7632ae628ccfd4576824477 Mon Sep 17 00:00:00 2001
From: ulrich
Date: Thu, 08 Apr 2021 10:37:10 +0000
Subject: [PATCH] REST-Konformitaet des StorageHandler verbessert

---
 src/de/uhilger/mediaz/api/StorageHandler.java  |   98 +++++++++++++++---
 src/de/uhilger/mediaz/store/FileStorage.java   |    4 
 src/de/uhilger/mediaz/entity/Titel.java        |   44 ++++++++
 src/de/uhilger/mediaz/store/Storage.java       |    2 
 src/mediaz_de_DE.properties                    |    2 
 src/de/uhilger/mediaz/Server.java              |   22 +--
 www/ui/js/app.js                               |   36 ++++---
 src/de/uhilger/mediaz/entity/Abspielliste.java |   48 +++++++++
 8 files changed, 207 insertions(+), 49 deletions(-)

diff --git a/src/de/uhilger/mediaz/Server.java b/src/de/uhilger/mediaz/Server.java
index 68a0ce4..3cad81f 100644
--- a/src/de/uhilger/mediaz/Server.java
+++ b/src/de/uhilger/mediaz/Server.java
@@ -104,23 +104,18 @@
 
     String wwwData = App.getInitParameter(App.getRs(App.RB_AP_WWW_DATA));
     File wwwDir = new File(wwwData);
-    //String ui = App.getInitParameter(App.getRs(App.RB_AP_UI));
-    //File uiDir = new File(ui);
 
     HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
-    server.createContext(ctx + App.getRs(RB_WEBROOT), 
-            new FileHandler(wwwDir.getAbsolutePath()));
+    server.createContext(ctx + App.getRs(RB_WEBROOT), new FileHandler(wwwDir.getAbsolutePath()));
     ablageorteEinklinken(server);
     server.createContext(ctx + App.getRs(RB_STORE), new StorageHandler());
-    //server.createContext(ctx + App.getRs(RB_UI_ROOT), new FileHandler(uiDir.getAbsolutePath()));    
     server.createContext(ctx + App.getRs(RB_STOP_SERVER), new StopServerHandler());
-    //server.createContext(ctx + App.getRs(RB_ABLAGE_TEST), new AblageTestHandler());
-    //server.createContext(ctx + App.getRs(RB_STORE_TEST), new StoreTestHandler());
     server.setExecutor(Executors.newFixedThreadPool(20));
     server.start();
   }
 
-  private void ablageorteEinklinken(HttpServer server) throws ClassNotFoundException, IOException {
+  private void ablageorteEinklinken(HttpServer server) 
+              throws ClassNotFoundException, IOException {
     String typ = Ablageort.class.getSimpleName();
     FileStorage store = new FileStorage(App.getInitParameter(App.getRs(App.RB_AP_CONF)));
     List<String> orte = store.list(typ);
@@ -129,12 +124,11 @@
       String ortName = i.next();
       Entity e = store.read(typ, ortName);
       if(e instanceof Ablageort) {
-        Ablageort ort = (Ablageort) e; 
-          Ablageort ablageort = (Ablageort) e;
-          logger.fine(ctx + ablageort.getUrl());
-          logger.fine(ablageort.getOrt());
-          server.createContext(ctx + ablageort.getUrl(), 
-                  new ListFileHandler(new File(ablageort.getOrt()).getAbsolutePath()));
+        Ablageort ablageort = (Ablageort) e;
+        logger.log(Level.FINE, "{0}{1}", new Object[]{ctx, ablageort.getUrl()});
+        logger.fine(ablageort.getOrt());
+        server.createContext(ctx + ablageort.getUrl(),  
+          new ListFileHandler(new File(ablageort.getOrt()).getAbsolutePath()));
       }
     }
   }
diff --git a/src/de/uhilger/mediaz/api/StorageHandler.java b/src/de/uhilger/mediaz/api/StorageHandler.java
index 3b8e010..255380f 100644
--- a/src/de/uhilger/mediaz/api/StorageHandler.java
+++ b/src/de/uhilger/mediaz/api/StorageHandler.java
@@ -27,7 +27,6 @@
 import de.uhilger.mediaz.store.FileStorage;
 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;
@@ -48,13 +47,29 @@
 
   
   /*
+  
+    PUT Die angegebene Ressource wird angelegt. Wenn die Ressource bereits 
+           existiert, wird sie geändert. 
+  
     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
+    1. HTTP GET Ablageort/[Name]  - Liefere den Ablageort namens [Name] als JSON
+    2. HTTP GET Ablageort/liste/  - Liefere eine Liste mit Namen aller Ablageorte
+                                     Es duerfen also keine Elemente namens "liste" angelegt werden
+    3. HTTP GET Ablageort/        - Liefere eine Liste aller Ablageort-Objekte als JSON
+    4. HTTP PUT Ablageort/[Name]  - Die angegebene Ressource wird angelegt. Wenn die Ressource 
+                                     bereits existiert, wird sie geändert. 
+    5. HTTP DELETE                - loesche den Ablageort
+    
+  
+  
+    falsch:
+    1. HTTP GET Ablageort/[Name]  - Liefere den Ablageort namens [Name] als JSON
+    2. HTTP GET Ablageort/liste/  - Liefere eine Liste mit Namen aller Ablageorte
+    2. HTTP GET Ablageort/  - Liefere eine Liste aller Ablageort-Objekte 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:
   
@@ -64,18 +79,14 @@
     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"
+    HTTP GET an /mz/api/store/Ablageort/[Name]
+    liest den Ablageort namens [Name]
   
-    HTTP POST an /mz/api/store/Ablageort
-    schreibt den neuen Ablageort im Body der Anfrage (Neu)
+    HTTP PUT an /mz/api/store/Ablageort/[Name]
+    wenn [Name] existiert: Aenderung, sonst neu anlegen
   
-    HTTP PUT an /mz/api/store/Ablageort
-    sucht den Ablageort mit dem Namen laut Body der Anfrage 
-    und schreibt den Inhalt aus der Anfrage in die Datei (Aenderung)
-  
-    HTTP DELETE an /mz/api/store/Ablageort/Katalog
-    löscht den Ablageort namens "Katalog"
+    HTTP DELETE an /mz/api/store/Ablageort/[Name]
+    löscht den Ablageort namens [Name]
   
   */
   
@@ -110,11 +121,12 @@
         break;
         
       case HTTP_PUT:
-        response = aendern(e);
+        response = put(e);
         break;
         
       case HTTP_POST:
-        response = neu(e);
+        response = "nicht unterstuertzt.";
+        code = 404;
         break;
         
       case HTTP_DELETE:
@@ -133,6 +145,51 @@
     os.close();        
   }
   
+  private String put(HttpExchange e) throws IOException {
+    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]; // alter Name, wenn Aenderung
+    if(!elemName.equalsIgnoreCase(App.getRs(RB_EP_LISTE))) {
+      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(bodyLesen(e), fs.typeFromName(type).getType());
+      if(o instanceof Entity) {
+        Entity entity = (Entity) o;
+        if(fs.exists(type, elemName)) {
+          fs.delete(type, elemName);
+          fs.write(entity, true);
+        } else {
+          fs.write(entity, false);
+        }
+        return type + App.getRs(Server.RB_SLASH) + entity.getName();
+      } else {
+        return "Ungueltiges Objekt im Body.";
+      }
+    } else {
+      return "Ungueltiger Elementname: " + App.getRs(RB_EP_LISTE);
+    }
+  }
+  
+  /*
+  private String schreiben(FileStorage fs, String typ, String name, String body, boolean overwrite) {
+    Gson gson = new Gson();
+    logger.log(Level.FINE, "type: {0}, token: {1}", new Object[]{typ, fs.typeFromName(typ).getType().getTypeName()});
+    Object o = gson.fromJson(body, fs.typeFromName(typ).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());
+        String filename = file.getName();
+        return typ + FileHandler.STR_BLANK + filename;
+      }
+    }    
+    return typ + FileHandler.STR_BLANK + " etwas Seltsames ist passiert.";
+  }
+  */
+  /*
   private String neu(HttpExchange e) throws IOException {
     return schreiben(e, false);
   }
@@ -140,7 +197,9 @@
   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));
@@ -162,6 +221,7 @@
     }
     return type + FileHandler.STR_BLANK + " Operation 'neu' fuer bereits existierende Entitaet.";
   }
+  */
   
   /*
   private String aendern(HttpExchange e) throws IOException {
@@ -184,7 +244,7 @@
     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))) {
+      if(elems[elems.length - 1].equalsIgnoreCase(App.getRs(RB_EP_LISTE))) {
         String type = elems[elems.length - 2];
         logger.fine(type);
         list = fs.list(type);
diff --git a/src/de/uhilger/mediaz/entity/Abspielliste.java b/src/de/uhilger/mediaz/entity/Abspielliste.java
new file mode 100644
index 0000000..0f6ef6f
--- /dev/null
+++ b/src/de/uhilger/mediaz/entity/Abspielliste.java
@@ -0,0 +1,48 @@
+/*
+  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.entity;
+
+import java.util.List;
+
+/**
+ *
+ * @author ulrich
+ */
+public class Abspielliste implements Entity {
+  
+  private String name;
+  private List<Titel> titel;
+
+  public List<Titel> getTitel() {
+    return titel;
+  }
+
+  public void setTitel(List titel) {
+    this.titel = titel;
+  }
+
+  @Override
+  public String getName() {
+    return name;
+  }
+  
+  public void setName(String name) {
+    this.name = name;
+  }
+
+}
diff --git a/src/de/uhilger/mediaz/entity/Titel.java b/src/de/uhilger/mediaz/entity/Titel.java
new file mode 100644
index 0000000..51fb606
--- /dev/null
+++ b/src/de/uhilger/mediaz/entity/Titel.java
@@ -0,0 +1,44 @@
+/*
+  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.entity;
+
+/**
+ *
+ * @author ulrich
+ */
+public class Titel {
+  private String katalogUrl;
+  private String name;
+
+  public String getKatalogUrl() {
+    return katalogUrl;
+  }
+
+  public void setKatalogUrl(String katalogUrl) {
+    this.katalogUrl = katalogUrl;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String titel) {
+    this.name = titel;
+  }
+  
+}
diff --git a/src/de/uhilger/mediaz/store/FileStorage.java b/src/de/uhilger/mediaz/store/FileStorage.java
index 217420c..b9f5df8 100644
--- a/src/de/uhilger/mediaz/store/FileStorage.java
+++ b/src/de/uhilger/mediaz/store/FileStorage.java
@@ -218,4 +218,8 @@
     return list;
   }
   
+  public boolean exists(String typ, String name) {
+    return getFile(typ, name).exists();
+  }
+  
 }
diff --git a/src/de/uhilger/mediaz/store/Storage.java b/src/de/uhilger/mediaz/store/Storage.java
index 7a1803e..3f63bc8 100644
--- a/src/de/uhilger/mediaz/store/Storage.java
+++ b/src/de/uhilger/mediaz/store/Storage.java
@@ -102,4 +102,6 @@
    * @return true, wenn geloeschn, false wenn nicht
    */
   public boolean delete(String typ, String name);
+  
+  public boolean exists(String typ, String name);
 }
diff --git a/src/mediaz_de_DE.properties b/src/mediaz_de_DE.properties
index bc25054..63a69fc 100644
--- a/src/mediaz_de_DE.properties
+++ b/src/mediaz_de_DE.properties
@@ -10,7 +10,7 @@
 webroot=/
 # uiroot=/ui
 store=/api/store
-epliste=liste/
+epliste=liste
 stopServer=/api/server/stop
 testAblage=/api/test/ablage
 testStore=/api/test/store
diff --git a/www/ui/js/app.js b/www/ui/js/app.js
index ded0e0e..02cf400 100644
--- a/www/ui/js/app.js
+++ b/www/ui/js/app.js
@@ -193,19 +193,22 @@
           document.querySelector('#abspieler-url').value
         );
         var daten = JSON.stringify(abspieler);        
-        if(typeof pl === "undefined" || pl.key !== plname) {
+        //if(typeof pl === "undefined" || pl.key !== plname) {
+        if(typeof pl.name === "undefined" || pl.name.length < 1) {
           // neu
-          self.http_post('../api/store/Abspieler', daten, function (responseText) {
+          self.http_put('../api/store/Abspieler/' + plname, daten, function (responseText) {
             // hier die Antwort verarbeiten
+            self.abspieler_auswahl_fuellen();
+            self.abspieler_liste();
           });
         } else {
           // aendern
-          self.http_put('../api/store/Abspieler', daten, function (responseText) {
+          self.http_put('../api/store/Abspieler/' + pl.name, daten, function (responseText) {
             // hier die Antwort verarbeiten
+            self.abspieler_auswahl_fuellen();
+            self.abspieler_liste();
           });
         }
-        //document.querySelector(".zentraler-inhalt").innerHTML = '';
-        self.abspieler_liste();
       });
       self.addEvtListener('#cancel-btn', 'click', function () {
         //document.querySelector(".zentraler-inhalt").innerHTML = '';
@@ -221,6 +224,7 @@
               // hier die Antwort verarbeiten
               self.dialog_schliessen();
               //document.querySelector(".zentraler-inhalt").innerHTML = '';
+              self.abspieler_auswahl_fuellen();
               self.abspieler_liste();
             });
           });
@@ -240,19 +244,20 @@
           document.querySelector('#einstellung-value').value
         );
         var daten = JSON.stringify(pref);        
-        if(typeof k === "undefined" || k.key !== pkey) {
+        //if(typeof k === "undefined" || k.key !== pkey) {
+        if(typeof k.key === "undefined" ||  k.key.length < 1) {
           // neu
-          self.http_post('../api/store/Einstellung', daten, function (responseText) {
+          self.http_put('../api/store/Einstellung/' + pkey, daten, function (responseText) {
             // hier die Antwort verarbeiten
+            self.prefs_liste();
           });
         } else {
           // aendern
-          self.http_put('../api/store/Einstellung', daten, function (responseText) {
+          self.http_put('../api/store/Einstellung/' + k.key, daten, function (responseText) {
             // hier die Antwort verarbeiten
+            self.prefs_liste();
           });
         }
-        //document.querySelector(".zentraler-inhalt").innerHTML = '';
-        self.prefs_liste();
       });
       self.addEvtListener('#cancel-btn', 'click', function () {
         //document.querySelector(".zentraler-inhalt").innerHTML = '';
@@ -296,19 +301,20 @@
           document.querySelector('#ablageort-url').value
         );
         var daten = JSON.stringify(a);        
-        if(typeof ort === "undefined" || ort.name !== aName) {
+        //if(typeof ort === "undefined" || ort.name !== aName) {
+        if(typeof ort.name === "undefined"  || ort.name.length < 1) {
           // neu
-          self.http_post('../api/store/Ablageort', daten, function (responseText) {
+          self.http_put('../api/store/Ablageort/' + aName, daten, function (responseText) {
             // hier die Antwort verarbeiten
+            self.ablageort_liste();
           });
         } else {
           // aendern
-          self.http_put('../api/store/Ablageort', daten, function (responseText) {
+          self.http_put('../api/store/Ablageort/' + ort.name, daten, function (responseText) {
             // hier die Antwort verarbeiten
+            self.ablageort_liste();
           });
         }
-        //document.querySelector(".zentraler-inhalt").innerHTML = '';
-        self.ablageort_liste();
       });
       self.addEvtListener('#cancel-btn', 'click', function () {
         //document.querySelector(".zentraler-inhalt").innerHTML = '';

--
Gitblit v1.9.3