/*
|
http-cm - File management extensions to jdk.httpserver
|
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.httpserver.cm;
|
|
import com.google.gson.Gson;
|
import com.sun.net.httpserver.Authenticator;
|
import com.sun.net.httpserver.Headers;
|
import com.sun.net.httpserver.HttpExchange;
|
import de.uhilger.httpserver.base.HttpResponder;
|
import de.uhilger.httpserver.base.HttpHelper;
|
import de.uhilger.httpserver.base.handler.FileHandler;
|
import de.uhilger.httpserver.image.Datei;
|
import de.uhilger.httpserver.image.ImageActor;
|
import de.uhilger.httpserver.image.ImageThread;
|
import de.uhilger.httpserver.image.ImageThread.ThreadListener;
|
import de.uhilger.httpserver.oauth.BearerAuthenticator;
|
import java.io.BufferedReader;
|
import java.io.File;
|
import java.io.FileInputStream;
|
import java.io.FileOutputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.io.InputStreamReader;
|
import java.io.OutputStream;
|
import java.net.URLDecoder;
|
import java.nio.file.DirectoryStream;
|
import java.nio.file.Files;
|
import java.nio.file.Path;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.Enumeration;
|
import java.util.List;
|
import java.util.logging.Logger;
|
import java.util.logging.Level;
|
import java.util.zip.Adler32;
|
import java.util.zip.CheckedOutputStream;
|
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipFile;
|
import java.util.zip.ZipOutputStream;
|
|
/**
|
* <p>Der FileManager verknuepft einen HTTP-Endpunkt mit einem Ordner des lokalen
|
* Dateisystems.</p>
|
*
|
* <p>HTTP GET fuer eine Datei innerhalb dieses Ordners liefert den Dateiinhalt aus</p>
|
*
|
* <p>HTTP GET fuer einen Ordner liefert eine Liste von dessen Inhalt in JSON</p>
|
*
|
* <p>HTTP PUT fuer eine Datei ueberschreibt eine bestehende Datei mit dem im Body
|
* uebergebenen Inhalt oder legt eine Datei mit diesem Inhalt an</p>
|
*
|
* <p>HTTP POST fuer eine Datei legt eine neue Datei mit dem im Body uebergebenen
|
* Inhalt an oder erzeugt eine neue Datei mit einer laufenden Nummer, falls
|
* diese Datei schon existiert</p>
|
*
|
* <p>HTTP POST fuer einen Ordner legt einen neuen Ordner an wenn er noch nicht
|
* existiert oder erzeugt einen HTTP-Fehler 422</p>
|
*
|
* <p>HTTP DELETE loescht die Liste der Dateien und Ordner im Body</p>
|
*
|
* <p>HTTP PUT ?copyFrom=pfad 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.</p>
|
*
|
* <p>HTTP PUT ?moveFrom=pfad 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.</p>
|
*
|
* <p>HTTP PUT mit ?duplicate legt eine Kopie der Datei an</p>
|
*
|
* <p>HTTP PUT mit '?renameTo=neuer Name' benennt die Datei oder den Ordner um,
|
* sofern der neue Name noch nicht vergeben ist</p>
|
*
|
* <p>HTTP PUT mit '?zip' packt den Ordner</p>
|
*
|
* <p>HTTP PUT mit '?unzip' entpackt eine Datei</p>
|
*
|
* <p>Namenskonventionen:<br>
|
* Ein Pfad mit Schraegstrich ('/') am Ende bezeichnet einen Ordner<br>
|
* Ein Pfad ohne Schraegstrich ('/') am Ende bezeichnet eine Datei</p>
|
*
|
* @author Ulrich Hilger
|
* @version 1, 13. Mai 2021
|
*/
|
public class FileManager extends FileHandler implements ThreadListener {
|
|
/* Der Logger fuer diesen ListFileHandler */
|
private static final Logger logger = Logger.getLogger(FileManager.class.getName());
|
|
/*
|
private static final String[] specialChars = {new String("\u00c4"), new String("\u00d6"),
|
new String("\u00dc"), new String("\u00e4"), new String("\u00f6"), new String("\u00fc"), new String("\u00df")};
|
*/
|
|
//public static final String UNWANTED_PATTERN = "[^a-zA-Z_0-9 ]";
|
/* HTTP Methoden */
|
|
public static final String UTF8 = "UTF-8";
|
|
public static final String STR_SLASH = "/";
|
public static final String STR_DOT = ".";
|
|
public static final String P_COPY = "copyFrom";
|
public static final String P_MOVE = "moveFrom";
|
public static final String P_DUPLICATE = "duplicate";
|
public static final String P_RENAME = "renameTo";
|
public static final String P_ZIP = "zip";
|
public static final String P_UNZIP = "unzip";
|
|
public static final int OP_COPY = 1;
|
public static final int OP_MOVE = 2;
|
public static final int OP_DELETE = 3;
|
|
public static final String ATTR_ROLE = "role";
|
|
private final List waitingThreads;
|
private final int maxThreads;
|
private int threadCount;
|
//private String role;
|
|
//public FileManager(String absoluteDirectoryPathAndName, String role, String ctx) {
|
public FileManager() {
|
//super(absoluteDirectoryPathAndName, ctx);
|
//super(absoluteDirectoryPathAndName);
|
waitingThreads = new ArrayList();
|
maxThreads = 4;
|
threadCount = 0;
|
//this.role = role;
|
}
|
|
@Override
|
public void handle(HttpExchange e) throws IOException {
|
Authenticator a = e.getHttpContext().getAuthenticator();
|
if(a instanceof BearerAuthenticator) {
|
BearerAuthenticator auth = (BearerAuthenticator) a;
|
//Realm realm = auth.getRealm();
|
String userId = e.getPrincipal().getUsername();
|
if(auth.hasRole(userId, e.getHttpContext().getAttributes().get(ATTR_ROLE).toString())) {
|
String method = e.getRequestMethod();
|
logger.fine("method: " + method);
|
HttpHelper helper = new HttpHelper();
|
switch (method) {
|
case HttpHelper.HTTP_GET:
|
liste(e, helper);
|
break;
|
case HttpHelper.HTTP_PUT:
|
put(e, helper);
|
break;
|
case HttpHelper.HTTP_POST:
|
speichern(e, helper);
|
break;
|
case HttpHelper.HTTP_DELETE:
|
loeschen(e, helper);
|
break;
|
}
|
} else {
|
standardHeaderUndAntwort(e, SC_FORBIDDEN, "Fehlende Rolle.");
|
}
|
} else {
|
standardHeaderUndAntwort(e, SC_FORBIDDEN, "Fehlende Rolle.");
|
}
|
}
|
|
private void put(HttpExchange exchange, HttpHelper helper) throws IOException {
|
String query = exchange.getRequestURI().getQuery();
|
if (query != null) {
|
String[] params = query.split("=");
|
for (String param : params) {
|
logger.fine("param: " + param);
|
}
|
switch (params[0]) {
|
case P_COPY:
|
copyOrMove(exchange, params[1], helper.getFileName(exchange), OP_COPY);
|
break;
|
case P_MOVE:
|
copyOrMove(exchange, params[1], helper.getFileName(exchange), OP_MOVE);
|
break;
|
case P_DUPLICATE:
|
if(Boolean.parseBoolean(params[1])) {
|
String neuerDateiName = duplizieren(exchange, helper);
|
logger.fine("neuer Name: " + neuerDateiName);
|
standardHeaderUndAntwort(exchange, SC_OK, neuerDateiName);
|
}
|
break;
|
case P_RENAME:
|
String neuerDateiName = umbenennen(exchange, helper, params[1]);
|
logger.fine("neuer Name: " + neuerDateiName);
|
standardHeaderUndAntwort(exchange, SC_OK, neuerDateiName);
|
break;
|
case P_ZIP:
|
String path = exchange.getRequestURI().toString();
|
logger.fine(path);
|
String antwort = packFolder(helper.getFileName(exchange), path, exchange);
|
if(antwort.equalsIgnoreCase("ok")) {
|
standardHeaderUndAntwort(exchange, SC_OK, antwort);
|
} else {
|
standardHeaderUndAntwort(exchange, SC_UNPROCESSABLE_ENTITY, antwort);
|
}
|
break;
|
case P_UNZIP:
|
path = exchange.getRequestURI().toString();
|
logger.fine(path);
|
antwort = extractZipfile(helper.getFileName(exchange), path, exchange);
|
if(antwort.equalsIgnoreCase("ok")) {
|
standardHeaderUndAntwort(exchange, SC_OK, antwort);
|
} else {
|
standardHeaderUndAntwort(exchange, SC_UNPROCESSABLE_ENTITY, antwort);
|
}
|
break;
|
}
|
} else {
|
speichern(exchange, helper);
|
}
|
}
|
|
public class DirList {
|
private String pfad;
|
private List<Datei> dateien;
|
|
public String getPfad() {
|
return pfad;
|
}
|
|
public void setPfad(String pfad) {
|
this.pfad = pfad;
|
}
|
|
public List<Datei> getDateien() {
|
return dateien;
|
}
|
|
public void setDateien(List<Datei> dateien) {
|
this.dateien = dateien;
|
}
|
|
|
}
|
|
private void liste(HttpExchange e, HttpHelper helper) throws IOException {
|
String path = e.getRequestURI().toString();
|
logger.fine(path);
|
String fName = helper.getFileName(e);
|
String dirListPath = e.getHttpContext().getPath() + fName;
|
if (path.endsWith(STR_SLASH)) {
|
logger.fine("fName: " + fName);
|
File dir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fName);
|
logger.fine("absPath: " + dir.getAbsolutePath());
|
File[] files = dir.listFiles(new ImageFileFilter());
|
if(files != null && files.length > 0) {
|
Arrays.sort(files);
|
ArrayList liste = new ArrayList();
|
for (File file : files) {
|
Datei datei = new Datei();
|
String dateiName = file.getName();
|
datei.setName(dateiName);
|
if (file.isDirectory()) {
|
datei.setTyp(Datei.TYP_ORDNER);
|
} else {
|
datei.setTyp(Datei.TYP_DATEI);
|
}
|
//datei.setPfad(e.getHttpContext().getPath() + fName);
|
String lowerName = dateiName.toLowerCase();
|
if (lowerName.endsWith(ImageActor.JPEG)
|
|| lowerName.endsWith(ImageActor.JPG)
|
|| lowerName.endsWith(ImageActor.PNG)) {
|
datei.setBild(true);
|
String ext = dateiName.substring(dateiName.lastIndexOf(STR_DOT));
|
String ohneExt = dateiName.substring(0, dateiName.lastIndexOf(STR_DOT));
|
datei.setMiniurl(ohneExt + ImageActor.TN + ext);
|
buildImgSrc(file, datei, ohneExt, ext);
|
}
|
liste.add(datei);
|
}
|
while(threadCount > 0) {
|
try {
|
Thread.sleep(50);
|
} catch (InterruptedException ex) {
|
Logger.getLogger(FileManager.class.getName()).log(Level.SEVERE, null, ex);
|
}
|
}
|
if(liste.size() > 0) {
|
DirList list = new DirList();
|
list.setPfad(dirListPath);
|
list.setDateien(liste);
|
Gson gson = new Gson();
|
//String json = gson.toJson(liste);
|
String json = gson.toJson(list);
|
//byte[] bytes = json.getBytes();
|
//logger.fine("json: '" + json + "'");
|
HttpResponder r = new HttpResponder();
|
r.antwortSenden(e, SC_OK, json);
|
} else {
|
emptyListResponse(e);
|
}
|
} else {
|
emptyListResponse(e);
|
}
|
} else {
|
String lowerName = fName.toLowerCase();
|
if(lowerName.contains(ImageActor.B64)) {
|
ImageActor actor = new ImageActor();
|
String fromName = fName.replace(ImageActor.B64, "");
|
File fromFile = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fromName);
|
File toFile = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fName);
|
logger.fine("from " + fromFile.getAbsolutePath() + ", to " + toFile.getAbsolutePath());
|
if(!toFile.exists()) {
|
actor.b64Image(fromFile, toFile);
|
}
|
super.handle(e);
|
} else {
|
super.handle(e);
|
}
|
}
|
}
|
|
// data:[<mime type>][;charset=<Zeichensatz>][;base64],<Daten>
|
/*
|
[So. Juni 13 13:23:32 MESZ 2021] FEIN:
|
file: /home/ulrich/helix-files/bild-test/10419903-14-2-1920-r.jpg,
|
relname: bild-test/10419903-14-2-1920-r.jpg, ohneExt: 10419903-14-2-1920-r, ext: .jpg (de.uhilger.helix.FileManager buildImgSrc)
|
|
*/
|
private void buildImgSrc(File file, Datei datei, String ohneExt, String ext) throws IOException {
|
//logger.fine("file: " + file.getAbsolutePath() + ", ohneExt: " + ohneExt + ", ext: " + ext);
|
File dir = file.getParentFile();
|
String newRelName = ohneExt + ImageActor.TN + ImageActor.B64 + ext;
|
File b64File = new File(dir, newRelName);
|
//logger.fine("b64File: " + b64File.getAbsolutePath());
|
if(!b64File.exists()) {
|
//BildErzeuger be = new BildErzeuger();
|
//be.bildErzeugen(dir, newRelName, BildErzeuger.TN, 120, b64File);
|
ImageThread it = new ImageThread(dir, newRelName, ImageActor.TN, 120, b64File, datei, ext);
|
it.addListener(this);
|
if(threadCount < maxThreads) {
|
++threadCount;
|
//logger.fine("Thread started, threadCount: " + threadCount);
|
it.start();
|
} else {
|
waitingThreads.add(it);
|
//logger.fine("Thread added to wait queue.");
|
}
|
} else {
|
ImageActor be = new ImageActor();
|
be.setImgSrc(datei, ext, b64File);
|
}
|
}
|
|
@Override
|
public void finished() {
|
--threadCount;
|
//logger.fine("Thread finished, threadCound now: " + threadCount);
|
if (threadCount < maxThreads) {
|
if (waitingThreads.size() > 0) {
|
Object o = waitingThreads.get(0);
|
if (o instanceof ImageThread) {
|
waitingThreads.remove(o);
|
ImageThread it = (ImageThread) o;
|
++threadCount;
|
//logger.fine("Thread started from wait queue, threadCount now: " + threadCount);
|
it.start();
|
}
|
}
|
}
|
}
|
|
private void emptyListResponse(HttpExchange e) throws IOException {
|
HttpResponder r = new HttpResponder();
|
String json = "{}";
|
logger.log(Level.FINE, "json: ''{0}''", json);
|
r.antwortSenden(e, SC_OK, json);
|
}
|
|
private void speichern(HttpExchange exchange, HttpHelper helper) throws IOException {
|
String fileName = helper.getFileName(exchange);
|
logger.info("fileName: " + fileName);
|
|
// file ist die Datei, um die es geht
|
File file = new File(exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fileName);
|
|
String method = exchange.getRequestMethod();
|
if (fileName.endsWith(STR_SLASH)) {
|
logger.info("neuer Ordner: " + file.getAbsolutePath());
|
// neuen Ordner erstellen oder ablehnen, wenn der Ordner schon existiert
|
if (method.equalsIgnoreCase(HttpHelper.HTTP_POST)) {
|
if (!file.exists()) {
|
file.mkdir();
|
standardHeaderUndAntwort(exchange, SC_OK, file.getAbsolutePath());
|
} else {
|
String antwort = "Ordner existiert bereits.";
|
standardHeaderUndAntwort(exchange, SC_UNPROCESSABLE_ENTITY, antwort);
|
}
|
} else {
|
String antwort = "PUT fuer neuen Ordner nicht erlaubt, bitte POST verwenden.";
|
standardHeaderUndAntwort(exchange, SC_METHOD_NOT_ALLOWED, antwort);
|
}
|
} else {
|
logger.info("Datei speichern: " + file.getAbsolutePath());
|
// Datei speichern
|
if (method.equalsIgnoreCase(HttpHelper.HTTP_POST)) {
|
if (file.exists()) {
|
FileTransporter trans = new FileTransporter();
|
file = trans.getNewFileName(file);
|
}
|
} else if (method.equalsIgnoreCase(HttpHelper.HTTP_PUT)) {
|
if (file.exists()) {
|
/*
|
muss delete() sein?
|
pruefen: ueberschreibt der FileWriter den alteen Inhalt oder
|
entsteht eine unerwuenschte Mischung aus altem und neuem
|
Inhalt?
|
*/
|
file.delete();
|
} else {
|
file.getParentFile().mkdirs();
|
}
|
}
|
// Request Body mit dem Dateiinhalt in einen String lesen
|
StringBuilder sb = new StringBuilder();
|
InputStream is = exchange.getRequestBody();
|
BufferedReader in = new BufferedReader(new InputStreamReader(is));
|
String line = in.readLine();
|
while (line != null) {
|
sb.append(line);
|
line = in.readLine();
|
}
|
|
// dekodieren
|
String content = sb.toString();
|
logger.fine(content);
|
String decoded = URLDecoder.decode(content, UTF8);
|
logger.fine(decoded);
|
|
// in Datei schreiben
|
byte[] bytes = decoded.getBytes();
|
file.createNewFile();
|
OutputStream os = new FileOutputStream(file);
|
os.write(bytes);
|
os.flush();
|
os.close();
|
is.close();
|
|
// Antwort senden
|
standardHeaderUndAntwort(exchange, SC_OK, file.getAbsolutePath());
|
}
|
}
|
|
private void copyOrMove(HttpExchange exchange, String quelle, String ziel, int op) throws IOException {
|
logger.fine("quelle: " + quelle + ", ziel: " + ziel);
|
String[] dateiNamen = dateiliste(exchange);
|
copyOrMoveFiles(quelle, ziel, dateiNamen, op, exchange);
|
standardHeaderUndAntwort(exchange, SC_OK, "Dateien verarbeitet.");
|
}
|
|
private String copyOrMoveFiles(String fromPath, String toPath, String[] fileNames, int operation, HttpExchange e) throws IOException {
|
String result = null;
|
File srcDir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fromPath);
|
File targetDir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), toPath);
|
for (String fileName : fileNames) {
|
File srcFile = new File(srcDir, fileName);
|
logger.fine("srcFile: " + srcFile);
|
if (srcFile.isDirectory()) {
|
logger.fine("srcFile is directory.");
|
OrdnerBearbeiter bearbeiter = new OrdnerBearbeiter();
|
bearbeiter.setTargetDir(targetDir.toPath());
|
bearbeiter.setOperation(operation);
|
Files.walkFileTree(srcFile.toPath(), bearbeiter);
|
} else {
|
Path source = srcFile.toPath();
|
File destFile = targetDir.toPath().resolve(source.getFileName()).toFile();
|
if (destFile.exists()) {
|
FileTransporter trans = new FileTransporter();
|
destFile = trans.getNewFileName(destFile);
|
}
|
if (operation == OP_MOVE) {
|
String fname = srcFile.getName().toLowerCase();
|
if (fname.endsWith(ImageActor.JPEG)
|
|| fname.endsWith(ImageActor.JPG)
|
|| fname.endsWith(ImageActor.PNG)) {
|
moveImgFilesToDirectory(srcFile, srcDir, targetDir, false);
|
} else {
|
Files.move(source, destFile.toPath());
|
}
|
} else {
|
Files.copy(source, destFile.toPath());
|
}
|
}
|
}
|
return result;
|
}
|
|
private void loeschen(HttpExchange exchange, HttpHelper helper) throws IOException {
|
String[] dateiNamen = dateiliste(exchange);
|
String relPfad = helper.getFileName(exchange);
|
deleteFiles(relPfad, Arrays.asList(dateiNamen), exchange);
|
standardHeaderUndAntwort(exchange, SC_OK, "Dateien geloescht.");
|
}
|
|
private String[] dateiliste(HttpExchange exchange) throws IOException {
|
String body = new HttpHelper().bodyLesen(exchange);
|
logger.fine("dateien: " + body);
|
Gson gson = new Gson();
|
return gson.fromJson(body, String[].class);
|
}
|
|
public String duplizieren(HttpExchange exchange, HttpHelper helper) throws IOException {
|
String relPfad = helper.getFileName(exchange);
|
File srcFile = new File(exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), relPfad);
|
String fnameext = srcFile.getName();
|
int dotpos = fnameext.lastIndexOf(STR_DOT);
|
String fname = fnameext.substring(0, dotpos);
|
String ext = fnameext.substring(dotpos);
|
File srcDir = srcFile.getParentFile();
|
File destFile = new File(srcDir, fname + "-Kopie" + ext);
|
int i = 1;
|
while (destFile.exists()) {
|
destFile = new File(srcDir, fname + "-Kopie-" + Integer.toString(++i) + ext);
|
}
|
Files.copy(srcFile.toPath(), destFile.toPath());
|
return destFile.getName();
|
}
|
|
public String umbenennen(HttpExchange exchange, HttpHelper helper, String neuerName) throws IOException {
|
File neueDatei;
|
String relPfad = helper.getFileName(exchange);
|
File file = new File(exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), relPfad);
|
String fname = file.getName().toLowerCase();
|
if(fname.endsWith(ImageActor.JPEG) || fname.endsWith(ImageActor.JPG) || fname.endsWith(ImageActor.PNG)) {
|
neueDatei = renameImgFiles(file.getParentFile(), file, neuerName);
|
} else {
|
neueDatei = new File(file.getParentFile(), neuerName);
|
file.renameTo(neueDatei);
|
}
|
return neueDatei.getName();
|
}
|
|
public File renameImgFiles(File targetDir, File targetFile, String newName) throws IOException {
|
String alt;
|
String neu;
|
File neueDatei = targetFile;
|
|
int newdotpos = newName.lastIndexOf(STR_DOT);
|
String newfname = newName.substring(0, newdotpos);
|
String newext = newName.substring(newdotpos);
|
logger.fine("newfname: " + newfname + ", newext: " + newext);
|
|
String fnameext = targetFile.getName();
|
int dotpos = fnameext.lastIndexOf(STR_DOT);
|
String fname = fnameext.substring(0, dotpos);
|
String ext = fnameext.substring(dotpos);
|
logger.fine("fname: " + fname + ", ext: " + ext);
|
|
DirectoryStream<Path> stream = Files.newDirectoryStream(targetDir.toPath(), fname + "*" + ext); //"*.{txt,doc,pdf,ppt}"
|
for (Path path : stream) {
|
logger.fine(path.getFileName().toString());
|
alt = path.getFileName().toString();
|
logger.fine("alt: " + alt);
|
if(alt.contains(ImageActor.TN)) {
|
neu = newfname + ImageActor.TN + newext;
|
} else if (alt.contains(ImageActor.KL)) {
|
neu = newfname + ImageActor.KL + newext;
|
} else if(alt.contains(ImageActor.GR)) {
|
neu = newfname + ImageActor.GR + newext;
|
} else if(alt.contains(ImageActor.MT)) {
|
neu = newfname + ImageActor.MT + newext;
|
} else if(alt.contains(ImageActor.SM)) {
|
neu = newfname + ImageActor.SM + newext;
|
} else {
|
neu = newName;
|
}
|
neueDatei = new File(targetDir, neu);
|
path.toFile().renameTo(neueDatei);
|
}
|
stream.close();
|
return neueDatei;
|
}
|
|
|
private String deleteFiles(String relPath, List<String> fileNames, HttpExchange e) {
|
String result = null;
|
try {
|
logger.fine(fileNames.toString());
|
if (!relPath.startsWith(STR_DOT)) {
|
File targetDir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), relPath); // getTargetDir(relPath);
|
logger.fine("targetDir: " + targetDir);
|
for (String fileName : fileNames) {
|
File targetFile = new File(targetDir, fileName);
|
logger.fine(targetFile.getAbsolutePath());
|
if (targetFile.isDirectory()) {
|
OrdnerBearbeiter bearbeiter = new OrdnerBearbeiter();
|
bearbeiter.setOperation(OP_DELETE);
|
Files.walkFileTree(targetFile.toPath(), bearbeiter);
|
} else {
|
/*
|
Wenn targetFile mit jpg, jpeg oder png endet,
|
muss eine Unterfunktion eine Liste aller Dateien bilden,
|
die so heissen, also z.B. alle [Dateiname]*.jpg
|
*/
|
String fname = targetFile.getName().toLowerCase();
|
if (fname.endsWith(ImageActor.JPEG)
|
|| fname.endsWith(ImageActor.JPG)
|
|| fname.endsWith(ImageActor.PNG)) {
|
deleteImgFiles(targetDir, targetFile);
|
} else {
|
targetFile.delete();
|
}
|
}
|
}
|
result = "deleted";
|
}
|
} catch (Throwable ex) {
|
logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
|
}
|
return result;
|
}
|
|
private void deleteImgFiles(File targetDir, File targetFile) throws IOException {
|
String fnameext = targetFile.getName();
|
int dotpos = fnameext.lastIndexOf(STR_DOT);
|
String fname = fnameext.substring(0, dotpos);
|
String ext = fnameext.substring(dotpos);
|
logger.fine("fname: " + fname + ", ext: " + ext);
|
DirectoryStream<Path> stream = Files.newDirectoryStream(targetDir.toPath(), fname + "*" + ext); //"*.{txt,doc,pdf,ppt}"
|
for (Path path : stream) {
|
logger.fine(path.getFileName().toString());
|
Files.delete(path);
|
}
|
stream.close();
|
}
|
|
private void moveImgFilesToDirectory(File srcFile, File srcDir, File targetDir, boolean createDestDir) throws IOException {
|
String fnameext = srcFile.getName();
|
int dotpos = fnameext.lastIndexOf(STR_DOT);
|
String fname = fnameext.substring(0, dotpos);
|
String ext = fnameext.substring(dotpos);
|
logger.fine("fname: " + fname + ", ext: " + ext);
|
Path targetPath = targetDir.toPath();
|
DirectoryStream<Path> stream = Files.newDirectoryStream(srcDir.toPath(), fname + "*" + ext); //"*.{txt,doc,pdf,ppt}"
|
for (Path path : stream) {
|
logger.fine(path.getFileName().toString());
|
//Files.delete(path);
|
Files.move(path, targetPath.resolve(path.getFileName()));
|
}
|
stream.close();
|
}
|
|
private void standardHeaderUndAntwort(HttpExchange exchange, int status, String antwort) throws IOException {
|
Headers resHeaders = exchange.getResponseHeaders();
|
resHeaders.add(CONTENT_TYPE, HttpHelper.CT_TEXT_HTML);
|
new HttpResponder().antwortSenden(exchange, status, antwort);
|
}
|
|
/* --------- ZIP entpacken ---------------- */
|
|
public String extractZipfile(String fName, String relPath, HttpExchange e) {
|
logger.fine("fName: " + fName + ", relPath: " + relPath);
|
String result = null;
|
if (!relPath.startsWith(".")) {
|
try {
|
//File targetDir = new File(fileBase, relPath);
|
//File targetDir = getTargetDir(relPath);
|
File archive = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fName);
|
if(extract(archive)) {
|
result = "ok";
|
} else {
|
result = "error while extracting";
|
}
|
} catch(Exception ex) {
|
result = ex.getLocalizedMessage();
|
logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
|
}
|
} else {
|
result = "Falsche relative Pfadangabe.";
|
}
|
return result;
|
}
|
|
/**
|
* extract a given ZIP archive to the folder respective archive resides in
|
* @param archive the archive to extract
|
* @throws Exception
|
*/
|
private boolean extract(File archive) throws Exception {
|
ZipFile zipfile = new ZipFile(archive);
|
Enumeration en = zipfile.entries();
|
while(en.hasMoreElements()) {
|
ZipEntry zipentry = (ZipEntry) en.nextElement();
|
unzip(zipfile, zipentry, archive.getParent());
|
}
|
zipfile.close();
|
return true;
|
}
|
|
/**
|
* unzip a given entry of a given zip file to a given location
|
* @param zipfile the zip file to read an entry from
|
* @param zipentry the zip entry to read
|
* @param destPath the path to the destination location for the extracted content
|
* @throws IOException
|
*/
|
private void unzip(ZipFile zipfile, ZipEntry zipentry, String destPath) throws IOException {
|
byte buf[] = new byte[1024];
|
InputStream is = zipfile.getInputStream(zipentry);
|
String outFileName = destPath + File.separator + zipentry.getName();
|
File file = new File(outFileName);
|
if(!zipentry.isDirectory()) {
|
file.getParentFile().mkdirs();
|
if(!file.exists())
|
file.createNewFile();
|
FileOutputStream fos = new FileOutputStream(file);
|
int i = is.read(buf, 0, 1024);
|
while(i > -1) {
|
fos.write(buf, 0, i);
|
i = is.read(buf, 0, 1024);
|
}
|
fos.close();
|
is.close();
|
} else {
|
file.mkdirs();
|
}
|
}
|
|
/* --------------- Ordner packen ----------------- */
|
|
/**
|
* Einen Ordner packen.
|
*
|
* Als Ziel wird eine neue Datei mit Dateiendung '.zip' erzeugt, die so
|
* heisst wie der Ordner, der gapckt werden soll. Die Datei mit
|
* dem gepackten Ordnerinhalt wird in dem Ordner angelegt, der den zu
|
* packenden Ordner enthaelt.
|
*
|
* @param fName Name des zu packenden Ordners
|
* @param relPath relativer Pfad zum Ordner, der gepackt werden soll
|
* @return die Meldung mit dem Ergebnis. Wenn die Meldung nicht "ok" lautet
|
* wurde die ZIP-Datei nicht erzeugt und die Meldung nennt den Grund.
|
*/
|
public String packFolder(String fName, String relPath, HttpExchange e) {
|
if (!relPath.startsWith(".")) {
|
try {
|
//String fName = getFileName(e);
|
logger.fine("fName: " + fName);
|
if (fName.endsWith(STR_SLASH)) {
|
File dir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fName);
|
if(dir.isDirectory()) {
|
logger.fine("absPath: " + dir.getAbsolutePath());
|
File parentDir = dir.getParentFile();
|
StringBuilder fname = new StringBuilder();
|
fname.append(dir.getName());
|
fname.append(".zip");
|
File archiveFile = new File(parentDir, fname.toString());
|
pack(dir.getAbsolutePath(), archiveFile.getAbsolutePath());
|
return "ok";
|
} else {
|
return "kein Ordner";
|
}
|
} else {
|
return "kein Ordner";
|
}
|
} catch(Exception ex) {
|
String result = ex.getLocalizedMessage();
|
logger.log(Level.SEVERE, result, ex);
|
return result;
|
}
|
} else {
|
return "Falsche relative Pfadangabe";
|
}
|
}
|
|
/**
|
* pack the contents of a given folder into a new ZIP compressed archive
|
* @param folder absolute path and name of the folder to pack
|
* @param archive absolute path and name of the archive to create from the given files
|
* @throws Exception
|
*/
|
private boolean pack(String folder, String archive) throws Exception {
|
File file = new File(archive);
|
FileOutputStream fos = new FileOutputStream(file);
|
CheckedOutputStream checksum = new CheckedOutputStream(fos, new Adler32());
|
ZipOutputStream zos = new ZipOutputStream(checksum);
|
pack(zos, folder, "");
|
zos.flush();
|
zos.finish();
|
zos.close();
|
fos.flush();
|
fos.close();
|
return true;
|
}
|
|
/**
|
* go through the given file structure recursively
|
* @param zipFile the ZIP file to write to
|
* @param srcDir the directory to pack during this cycle
|
* @param subDir the subdirectory to append to names of file entries inside the archive
|
* @throws IOException
|
*/
|
private void pack(ZipOutputStream zipFile, String srcDir, String subDir) throws IOException {
|
File[] files = new File(srcDir).listFiles();
|
for(int i = 0; i < files.length; i++) {
|
if(files[i].isDirectory()) {
|
pack(zipFile, files[i].getAbsolutePath(), subDir + File.separator + files[i].getName());
|
}
|
else {
|
packFile(zipFile, subDir, files[i]);
|
}
|
}
|
}
|
|
/**
|
* pack a given file
|
* @param zipFile the ZIP archive to pack to
|
* @param dir the directory name to append to name of file entry inside archive
|
* @param file the file to pack
|
* @throws IOException
|
*/
|
private void packFile(ZipOutputStream zipFile, String dir, File file) throws IOException
|
{
|
FileInputStream fileinputstream = new FileInputStream(file);
|
byte buf[] = new byte[fileinputstream.available()];
|
fileinputstream.read(buf);
|
String dirWithSlashes = dir.replace('\\', '/');
|
//System.out.println("zipping " + dirWithSlashes + "/" + file.getName());
|
ZipEntry ze = new ZipEntry(dirWithSlashes + "/" + file.getName());
|
ze.setMethod(ZipEntry.DEFLATED);
|
zipFile.putNextEntry(ze);
|
zipFile.write(buf, 0, buf.length);
|
zipFile.closeEntry();
|
fileinputstream.close();
|
}
|
|
|
|
|
}
|