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