/*
|
neon-fm - Dateiverwaltung fuer neon
|
Copyright (C) 2024 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.neon.fm;
|
|
import com.sun.net.httpserver.HttpExchange;
|
import de.uhilger.neon.FileServer;
|
import de.uhilger.neon.HttpResponder;
|
import de.uhilger.fm.Duplicator;
|
import de.uhilger.fm.Mover;
|
import de.uhilger.fm.Renamer;
|
import de.uhilger.fm.Inflator;
|
import de.uhilger.fm.Deflator;
|
import java.io.IOException;
|
|
/**
|
* Aenderungen an bestehenden Dateien.
|
*
|
* @author Ulrich Hilger
|
* @version 0.1, 07.11.2024
|
*/
|
public class FileManipulator extends AbstractFileActor {
|
|
private static final String P_RENAME = "renameTo";
|
private static final String P_COPY = "copyFrom";
|
private static final String P_MOVE = "moveFrom";
|
private static final String P_DUPLICATE = "duplicate";
|
private static final String P_ZIP = "zip";
|
private static final String P_UNZIP = "unzip";
|
|
/**
|
* <p>
|
* Diese Methode ist als Reaktion auf einen HTTP PUT Aufruf an folgende URLs gedacht</p>
|
*
|
* <pre>
|
* PUT [url]
|
* [body]
|
* </pre>
|
*
|
* <pre>
|
* - Inhalt einer einzelnen Datei anlegen oder ueberschreiben: url=ziel, Dateiinhalt im Body
|
* - Liste mit Dateien kopieren (?copyFrom=quelle): url=ziel, Dateiliste im Body
|
* - Liste mit Dateien verschieben (?moveFrom=quelle): url=Ziel, Dateiliste im Body
|
* - einzelne Datei duplizieren (?duplicate): url=Zieldatei
|
* - einzelne Datei umbenennen (?renameTo=neuer Name): url=Datei oder -ordner
|
* - Ordner packen (?zip): url=Ordner
|
* - Zip-Datei entpacken (?unzip): url=Datei
|
* </pre>
|
*
|
*
|
* <pre>
|
* HTTP PUT /pfad/zur/datei.txt ueberschreibt eine bestehende Datei mit dem im Body
|
* uebergebenen Inhalt oder legt eine Datei mit diesem Inhalt an
|
*
|
* HTTP PUT /pfad/zum/zielordner?copyFrom=/pfad/zum/quellordner
|
* kopiert die Liste der Datei- oder Ordnernamen im Body
|
* der Anfrage vom Pfad in 'copyFrom' zum Pfad dieser Anfrage. Jede Datei, die
|
* im Ziel bereits existiert, bekommt im Ziel einen neuen Namen mit einer
|
* laufenden Nummer. Bei Ordnern, die im Ziel bereits existieren, bekommt der
|
* betreffende Ordner im Ziel zunaechst einen neuen Namen mit einer laufenden
|
* Nummer, dann wird der Quellordner ans Ziel kopiert.
|
*
|
* HTTP PUT /pfad/zum/zielordner?moveFrom=/pfad/zum/quellordner
|
* verschiebt die Liste der Datei- oder Ordnernamen im
|
* Body der Anfrage vom Pfad in 'moveFrom' zum Pfad dieser Anfrage. Jede Datei,
|
* die im Ziel bereits existiert, bekommt im Ziel einen neuen Namen mit einer
|
* laufenden Nummer. Bei Ordnern, die im Ziel bereits existieren, bekommt der
|
* betreffende Ordner im Ziel zunaechst einen neuen Namen mit einer laufenden
|
* Nummer, dann wird der Quellordner ans Ziel kopiert.
|
*
|
* HTTP PUT /pfad/zur/datei.txt?duplicate legt eine Kopie der Datei an
|
*
|
* HTTP PUT /pfad/zur/datei.txt?renameTo=neuer Name benennt die Datei oder den Ordner um,
|
* sofern der neue Name noch nicht vergeben ist
|
*
|
* HTTP PUT /pfad/zum/ordner?zip' packt den Ordner
|
*
|
* HTTP PUT /pfad/zur/datei.zip?unzip' entpackt eine Datei
|
*
|
* Eine Dateiliste im Body sieht z.B. wie folgt aus
|
* ["test.txt","dok","weitere-datei.bin","bild.jpg"]
|
*
|
* </pre>
|
*
|
* @param exchange das Objekt mit Infos zu HTTP-Request, -Response usw.
|
*/
|
public void change(HttpExchange exchange) {
|
try {
|
init(exchange);
|
String query = exchange.getRequestURI().getQuery();
|
if (query != null) {
|
String[] params = query.split(FileServer.STR_EQUAL);
|
switch (params[0]) {
|
case P_RENAME:
|
h.inspectFileName(params[1]);
|
String neuerDateiName = new Renamer().rename(/*fileName, */params[1], file);
|
antwort(exchange, HttpResponder.SC_OK, neuerDateiName);
|
break;
|
case P_COPY:
|
h.inspectFileName(params[1]);
|
copyOrMove(exchange, params[1], fileName, Mover.OP_COPY);
|
break;
|
case P_MOVE:
|
h.inspectFileName(params[1]);
|
copyOrMove(exchange, params[1], fileName, Mover.OP_MOVE);
|
break;
|
case P_DUPLICATE:
|
if (Boolean.parseBoolean(params[1])) {
|
String dup = new Duplicator().duplizieren(base, fileName);
|
//logger.fine("neuer Name: " + neuerDateiName);
|
antwort(exchange, HttpResponder.SC_OK, dup);
|
}
|
break;
|
case P_ZIP:
|
//String path = exchange.getRequestURI().toString();
|
zipAntwort(exchange, new Deflator().packFolder(fileName, /*path, */ base));
|
break;
|
case P_UNZIP:
|
//String path = exchange.getRequestURI().toString();
|
zipAntwort(exchange, new Inflator().extractZipfile(fileName, /*path,*/ base));
|
break;
|
default:
|
antwort(exchange, HttpResponder.SC_NOT_FOUND, "ungueltige Anfrage");
|
break;
|
}
|
} else {
|
if (fileName.endsWith(FileServer.STR_SLASH)) {
|
antwort(exchange, HttpResponder.SC_METHOD_NOT_ALLOWED, "PUT nicht erlaubt, POST verwenden.");
|
} else {
|
speichern(exchange);
|
}
|
}
|
} catch (IOException | IllegalArgumentException ex) {
|
fehlerAntwort(exchange, ex);
|
} finally {
|
free();
|
}
|
}
|
|
private void copyOrMove(HttpExchange exchange, String quelle, String ziel, int op) throws IOException {
|
String[] dateiNamen = dateiliste(exchange);
|
if (op == Mover.OP_COPY) {
|
new Mover().copy(quelle, ziel, dateiNamen, base);
|
} else {
|
new Mover().move(quelle, ziel, dateiNamen, base);
|
}
|
//new Mover().copyOrMoveFiles(quelle, ziel, dateiNamen, op, base);
|
antwort(exchange, HttpResponder.SC_OK, "Dateien verarbeitet.");
|
}
|
|
private void zipAntwort(HttpExchange exchange, String antw) throws IOException {
|
if (antw.equalsIgnoreCase("ok")) {
|
antwort(exchange, HttpResponder.SC_OK, antw);
|
} else {
|
antwort(exchange, HttpResponder.SC_UNPROCESSABLE_ENTITY, antw);
|
}
|
}
|
}
|