Dateien verwalten mit Modul jdk.httpserver
ulrich
2024-01-15 020a97355fdd8133da6cfd490b7b1e9618a1eb06
commit | author | age
7fdd7e 1 /*
U 2   http-cm - File management extensions to jdk.httpserver
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/>.
17  */
18 package de.uhilger.httpserver.cm;
19
20 import com.google.gson.Gson;
21 import com.sun.net.httpserver.Authenticator;
22 import com.sun.net.httpserver.Headers;
23 import com.sun.net.httpserver.HttpExchange;
24 import de.uhilger.httpserver.base.HttpResponder;
25 import de.uhilger.httpserver.base.HttpHelper;
26 import de.uhilger.httpserver.base.handler.FileHandler;
27 import de.uhilger.httpserver.image.Datei;
28 import de.uhilger.httpserver.image.ImageActor;
29 import de.uhilger.httpserver.image.ImageThread;
30 import de.uhilger.httpserver.image.ImageThread.ThreadListener;
31 import de.uhilger.httpserver.oauth.BearerAuthenticator;
32 import java.io.BufferedReader;
33 import java.io.File;
34 import java.io.FileOutputStream;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.io.InputStreamReader;
38 import java.io.OutputStream;
39 import java.net.URLDecoder;
40 import java.nio.file.DirectoryStream;
41 import java.nio.file.Files;
42 import java.nio.file.Path;
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.List;
46 import java.util.logging.Logger;
47 import java.util.logging.Level;
48
49 /**
50  * <p>Der FileManager verknuepft einen HTTP-Endpunkt mit einem Ordner des lokalen
51  * Dateisystems.</p>
52  *
53  * <p>HTTP GET fuer eine Datei innerhalb dieses Ordners liefert den Dateiinhalt aus</p>
54  *
55  * <p>HTTP GET fuer einen Ordner liefert eine Liste von dessen Inhalt in JSON</p>
56  *
57  * <p>HTTP PUT fuer eine Datei ueberschreibt eine bestehende Datei mit dem im Body
58  * uebergebenen Inhalt oder legt eine Datei mit diesem Inhalt an</p>
59  *
60  * <p>HTTP POST fuer eine Datei legt eine neue Datei mit dem im Body uebergebenen
61  * Inhalt an oder erzeugt eine neue Datei mit einer laufenden Nummer, falls
62  * diese Datei schon existiert</p>
63  *
64  * <p>HTTP POST fuer einen Ordner legt einen neuen Ordner an wenn er noch nicht
65  * existiert oder erzeugt einen HTTP-Fehler 422</p>
66  *
67  * <p>HTTP DELETE loescht die Liste der Dateien und Ordner im Body</p>
68  *
69  * <p>HTTP PUT ?copyFrom=pfad kopiert die Liste der Datei- oder Ordnernamen im Body
70  * der Anfrage vom Pfad in 'copyFrom' zum Pfad dieser Anfrage. Jede Datei, die
71  * im Ziel bereits existiert, bekommt im Ziel einen neuen Namen mit einer
72  * laufenden Nummer. Bei Ordnern, die im Ziel bereits existieren, bekommt der
73  * betreffende Ordner im Ziel zunaechst einen neuen Namen mit einer laufenden
74  * Nummer, dann wird der Quellordner ans Ziel kopiert.</p>
75  *
76  * <p>HTTP PUT ?moveFrom=pfad verschiebt die Liste der Datei- oder Ordnernamen im
77  * Body der Anfrage vom Pfad in 'moveFrom' zum Pfad dieser Anfrage. Jede Datei,
78  * die im Ziel bereits existiert, bekommt im Ziel einen neuen Namen mit einer
79  * laufenden Nummer. Bei Ordnern, die im Ziel bereits existieren, bekommt der
80  * betreffende Ordner im Ziel zunaechst einen neuen Namen mit einer laufenden
81  * Nummer, dann wird der Quellordner ans Ziel kopiert.</p>
82  *
83  * <p>HTTP PUT mit ?duplicate legt eine Kopie der Datei an</p>
84  *
85  * <p>HTTP PUT mit '?renameTo=neuer Name' benennt die Datei oder den Ordner um,
86  * sofern der neue Name noch nicht vergeben ist</p>
87  *
88  * <p>HTTP PUT mit '?zip' packt den Ordner</p>
89  *
90  * <p>HTTP PUT mit '?unzip' entpackt eine Datei</p>
91  * 
92  * <p>Namenskonventionen:<br>
93  * Ein Pfad mit Schraegstrich ('/') am Ende bezeichnet einen Ordner<br>
94  * Ein Pfad ohne Schraegstrich ('/') am Ende bezeichnet eine Datei</p>
95  *
96  * @author Ulrich Hilger
97  * @version 1, 13. Mai 2021
98  */
99 public class FileManager extends FileHandler implements ThreadListener {
100
101   /*
102   private static final String[] specialChars = {new String("\u00c4"), new String("\u00d6"),
103     new String("\u00dc"), new String("\u00e4"), new String("\u00f6"), new String("\u00fc"), new String("\u00df")};
104   */
105   
106   //public static final String UNWANTED_PATTERN = "[^a-zA-Z_0-9 ]";
107   /* HTTP Methoden */
108
109   public static final String UTF8 = "UTF-8";
110
111   public static final String STR_SLASH = "/";
112   public static final String STR_DOT = ".";
113   
114   public static final String P_COPY = "copyFrom";
115   public static final String P_MOVE = "moveFrom";
116   public static final String P_DUPLICATE = "duplicate";
117   public static final String P_RENAME = "renameTo";
118   public static final String P_ZIP = "zip";
119   public static final String P_UNZIP = "unzip";
120
121   public static final int OP_COPY = 1;
122   public static final int OP_MOVE = 2;
123   public static final int OP_DELETE = 3;
124   
125   public static final String ATTR_ROLE = "role";
126   
127   private final List waitingThreads;
128   private final int maxThreads;
129   private int threadCount;
130   //private String role;
131
132   //public FileManager(String absoluteDirectoryPathAndName, String role, String ctx) {
133   public FileManager() {
134     //super(absoluteDirectoryPathAndName, ctx);
135     //super(absoluteDirectoryPathAndName);
136     waitingThreads = new ArrayList();
137     maxThreads = 4;
138     threadCount = 0;
139     //this.role = role;
140   }
141
142   @Override
143   public void handle(HttpExchange e) throws IOException {
144     Authenticator a = e.getHttpContext().getAuthenticator();
145     if(a instanceof BearerAuthenticator) {
146       BearerAuthenticator auth = (BearerAuthenticator) a;
147       //Realm realm = auth.getRealm();
148       String userId = e.getPrincipal().getUsername();
149       if(auth.hasRole(userId, e.getHttpContext().getAttributes().get(ATTR_ROLE).toString())) {
150         String method = e.getRequestMethod();
5adf10 151         //logger.fine("method: " + method);
7fdd7e 152         HttpHelper helper = new HttpHelper();
U 153         switch (method) {
154           case HttpHelper.HTTP_GET:
155             liste(e, helper);
156             break;
157           case HttpHelper.HTTP_PUT:
158             put(e, helper);
159             break;
160           case HttpHelper.HTTP_POST:
161             speichern(e, helper);
162             break;
163           case HttpHelper.HTTP_DELETE:
164             loeschen(e, helper);
165             break;
166         }
167       } else {
168         standardHeaderUndAntwort(e, SC_FORBIDDEN, "Fehlende Rolle.");
169       }
170     } else {
171       standardHeaderUndAntwort(e, SC_FORBIDDEN, "Fehlende Rolle.");
172     }
173   }
174
175   private void put(HttpExchange exchange, HttpHelper helper) throws IOException {
176     String query = exchange.getRequestURI().getQuery();
177     if (query != null) {
178       String[] params = query.split("=");
179       for (String param : params) {
5adf10 180         //logger.fine("param: " + param);
7fdd7e 181       }
U 182       switch (params[0]) {
183         case P_COPY:
184           copyOrMove(exchange, params[1], helper.getFileName(exchange), OP_COPY);
185           break;
186         case P_MOVE:
187           copyOrMove(exchange, params[1], helper.getFileName(exchange), OP_MOVE);
188           break;
189         case P_DUPLICATE:
190           if(Boolean.parseBoolean(params[1])) {
191             String neuerDateiName = duplizieren(exchange, helper);
5adf10 192             //logger.fine("neuer Name: " + neuerDateiName);
7fdd7e 193             standardHeaderUndAntwort(exchange, SC_OK, neuerDateiName);
U 194           }
195           break;
196         case P_RENAME:
197           String neuerDateiName = umbenennen(exchange, helper, params[1]);
5adf10 198           //logger.fine("neuer Name: " + neuerDateiName);
7fdd7e 199           standardHeaderUndAntwort(exchange, SC_OK, neuerDateiName);
U 200           break;
201         case P_ZIP:
202           String path = exchange.getRequestURI().toString();
5adf10 203           //logger.fine(path);
020a97 204           String antwort = new Zipper().packFolder(helper.getFileName(exchange), path, exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString());
7fdd7e 205           if(antwort.equalsIgnoreCase("ok")) {
U 206             standardHeaderUndAntwort(exchange, SC_OK, antwort);
207           } else {
208             standardHeaderUndAntwort(exchange, SC_UNPROCESSABLE_ENTITY, antwort);
209           }
210           break;
211         case P_UNZIP:
212           path = exchange.getRequestURI().toString();
5adf10 213           //logger.fine(path);
020a97 214           antwort = new Unzipper().extractZipfile(helper.getFileName(exchange), path, exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString());
7fdd7e 215           if(antwort.equalsIgnoreCase("ok")) {
U 216             standardHeaderUndAntwort(exchange, SC_OK, antwort);
217           } else {
218             standardHeaderUndAntwort(exchange, SC_UNPROCESSABLE_ENTITY, antwort);
219           }
220           break;
221       }
222     } else {
223       speichern(exchange, helper);
224     }
225   }
66173f 226   
U 227   public class DirList {
228     private String pfad;
229     private List<Datei> dateien;
230
231     public String getPfad() {
232       return pfad;
233     }
234
235     public void setPfad(String pfad) {
236       this.pfad = pfad;
237     }
238
239     public List<Datei> getDateien() {
240       return dateien;
241     }
242
243     public void setDateien(List<Datei> dateien) {
244       this.dateien = dateien;
245     }
246     
247     
248   }
7fdd7e 249
U 250   private void liste(HttpExchange e, HttpHelper helper) throws IOException {
251     String path = e.getRequestURI().toString();
5adf10 252     //logger.fine(path);
7fdd7e 253     String fName = helper.getFileName(e);
66173f 254     String dirListPath = e.getHttpContext().getPath() + fName;
7fdd7e 255     if (path.endsWith(STR_SLASH)) {      
5adf10 256       //logger.fine("fName: " + fName);
7fdd7e 257       File dir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fName);
5adf10 258       //logger.fine("absPath: " + dir.getAbsolutePath());
7fdd7e 259       File[] files = dir.listFiles(new ImageFileFilter());
U 260       if(files != null && files.length > 0) {
261         Arrays.sort(files);
262         ArrayList liste = new ArrayList();
263         for (File file : files) {
264           Datei datei = new Datei();
265           String dateiName = file.getName();
266           datei.setName(dateiName);
267           if (file.isDirectory()) {
268             datei.setTyp(Datei.TYP_ORDNER);
269           } else {
270             datei.setTyp(Datei.TYP_DATEI);
271           }
66173f 272           //datei.setPfad(e.getHttpContext().getPath() + fName);
7fdd7e 273           String lowerName = dateiName.toLowerCase();
U 274           if (lowerName.endsWith(ImageActor.JPEG)
275                   || lowerName.endsWith(ImageActor.JPG)
276                   || lowerName.endsWith(ImageActor.PNG)) {
277             datei.setBild(true);
278             String ext = dateiName.substring(dateiName.lastIndexOf(STR_DOT));
279             String ohneExt = dateiName.substring(0, dateiName.lastIndexOf(STR_DOT));
280             datei.setMiniurl(ohneExt + ImageActor.TN + ext);
281             buildImgSrc(file, datei, ohneExt, ext);
282           }
283           liste.add(datei);
284         }
285         while(threadCount > 0) {
286           try {
287             Thread.sleep(50);
288           } catch (InterruptedException ex) {
289             Logger.getLogger(FileManager.class.getName()).log(Level.SEVERE, null, ex);
290           }
291         }
292         if(liste.size() > 0) {
66173f 293           DirList list = new DirList();
U 294           list.setPfad(dirListPath);
295           list.setDateien(liste);
7fdd7e 296           Gson gson = new Gson();
66173f 297           //String json = gson.toJson(liste);
U 298           String json = gson.toJson(list);
7fdd7e 299           //byte[] bytes = json.getBytes();
U 300           //logger.fine("json: '" + json + "'");
301           HttpResponder r = new HttpResponder();
302           r.antwortSenden(e, SC_OK, json);
303         } else {
304           emptyListResponse(e);      
305         }
306       } else {
307         emptyListResponse(e);      
308       }
309     } else {
310       String lowerName = fName.toLowerCase();
311       if(lowerName.contains(ImageActor.B64)) {
312         ImageActor actor = new ImageActor();
313         String fromName = fName.replace(ImageActor.B64, "");
314         File fromFile = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fromName);
315         File toFile = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fName);
5adf10 316         //logger.fine("from " + fromFile.getAbsolutePath() + ", to " + toFile.getAbsolutePath());
7fdd7e 317         if(!toFile.exists()) {
U 318           actor.b64Image(fromFile, toFile);
319         }
320         super.handle(e);
321       } else {
322         super.handle(e);
323       }
324     }
325   }
326   
327   //  data:[<mime type>][;charset=<Zeichensatz>][;base64],<Daten>
328   /*
329   [So. Juni 13 13:23:32 MESZ 2021] FEIN: 
330   file: /home/ulrich/helix-files/bild-test/10419903-14-2-1920-r.jpg, 
331   relname: bild-test/10419903-14-2-1920-r.jpg, ohneExt: 10419903-14-2-1920-r, ext: .jpg (de.uhilger.helix.FileManager buildImgSrc)
332
333   */
334   private void buildImgSrc(File file, Datei datei, String ohneExt, String ext) throws IOException {
335     //logger.fine("file: " + file.getAbsolutePath() + ", ohneExt: " + ohneExt + ", ext: " + ext);
336     File dir = file.getParentFile();
337     String newRelName = ohneExt + ImageActor.TN + ImageActor.B64 + ext;
338     File b64File = new File(dir, newRelName);
339     //logger.fine("b64File: " + b64File.getAbsolutePath());
340     if(!b64File.exists()) {
341       //BildErzeuger be = new BildErzeuger();
342       //be.bildErzeugen(dir, newRelName, BildErzeuger.TN, 120, b64File);
343       ImageThread it = new ImageThread(dir, newRelName, ImageActor.TN, 120, b64File, datei, ext);
344       it.addListener(this);
345       if(threadCount < maxThreads) {
346         ++threadCount;
347         //logger.fine("Thread started, threadCount: " + threadCount);
348         it.start();
349       } else {
350         waitingThreads.add(it);
351         //logger.fine("Thread added to wait queue.");
352       }
353     } else {
354       ImageActor be = new ImageActor();
355       be.setImgSrc(datei, ext, b64File);
356     }
357   }
358   
359   @Override
360   public void finished() {
361     --threadCount;
362     //logger.fine("Thread finished, threadCound now: " + threadCount);
363     if (threadCount < maxThreads) {
364       if (waitingThreads.size() > 0) {
365         Object o = waitingThreads.get(0);
366         if (o instanceof ImageThread) {
367           waitingThreads.remove(o);
368           ImageThread it = (ImageThread) o;
369           ++threadCount;
370           //logger.fine("Thread started from wait queue, threadCount now: " + threadCount);
371           it.start();
372         }
373       }
374     }
375   }  
376   
377   private void emptyListResponse(HttpExchange e) throws IOException {
378     HttpResponder r = new HttpResponder();
379     String json = "{}";
5adf10 380     //logger.log(Level.FINE, "json: ''{0}''", json);
7fdd7e 381     r.antwortSenden(e, SC_OK, json);        
U 382   }
383
384   private void speichern(HttpExchange exchange, HttpHelper helper) throws IOException {
385     String fileName = helper.getFileName(exchange);
5adf10 386     //logger.info("fileName: " + fileName);
7fdd7e 387
U 388     // file ist die Datei, um die es geht
389     File file = new File(exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fileName);
390
391     String method = exchange.getRequestMethod();
392     if (fileName.endsWith(STR_SLASH)) {
5adf10 393       //logger.info("neuer Ordner: " + file.getAbsolutePath());
7fdd7e 394       // neuen Ordner erstellen oder ablehnen, wenn der Ordner schon existiert
U 395       if (method.equalsIgnoreCase(HttpHelper.HTTP_POST)) {
396         if (!file.exists()) {
397           file.mkdir();
398           standardHeaderUndAntwort(exchange, SC_OK, file.getAbsolutePath());
399         } else {
400           String antwort = "Ordner existiert bereits.";
401           standardHeaderUndAntwort(exchange, SC_UNPROCESSABLE_ENTITY, antwort);
402         }
403       } else {
404         String antwort = "PUT fuer neuen Ordner nicht erlaubt, bitte POST verwenden.";
405         standardHeaderUndAntwort(exchange, SC_METHOD_NOT_ALLOWED, antwort);        
406       }
407     } else {
5adf10 408       //logger.info("Datei speichern: " + file.getAbsolutePath());
7fdd7e 409       // Datei speichern
U 410       if (method.equalsIgnoreCase(HttpHelper.HTTP_POST)) {
411         if (file.exists()) {
412           FileTransporter trans = new FileTransporter();
413           file = trans.getNewFileName(file);
414         }
415       } else if (method.equalsIgnoreCase(HttpHelper.HTTP_PUT)) {
416         if (file.exists()) {
417           /*
418             muss delete() sein?
419             pruefen: ueberschreibt der FileWriter den alteen Inhalt oder 
420             entsteht eine unerwuenschte Mischung aus altem und neuem 
421             Inhalt?
422            */
423           file.delete();
424         } else {
425           file.getParentFile().mkdirs();
426         }
427       }
428       // Request Body mit dem Dateiinhalt in einen String lesen
429       StringBuilder sb = new StringBuilder();
430       InputStream is = exchange.getRequestBody();
431       BufferedReader in = new BufferedReader(new InputStreamReader(is));
432       String line = in.readLine();
433       while (line != null) {
434         sb.append(line);
435         line = in.readLine();
436       }
437
438       // dekodieren
439       String content = sb.toString();
5adf10 440       //logger.fine(content);
7fdd7e 441       String decoded = URLDecoder.decode(content, UTF8);
5adf10 442       //logger.fine(decoded);
7fdd7e 443
U 444       // in Datei schreiben
445       byte[] bytes = decoded.getBytes();
446       file.createNewFile();
447       OutputStream os = new FileOutputStream(file);
448       os.write(bytes);
449       os.flush();
450       os.close();
451       is.close();
452
453       // Antwort senden
454       standardHeaderUndAntwort(exchange, SC_OK, file.getAbsolutePath());
455     }
456   }
457
458   private void copyOrMove(HttpExchange exchange, String quelle, String ziel, int op) throws IOException {
5adf10 459     //logger.fine("quelle: " + quelle + ", ziel: " + ziel);
7fdd7e 460     String[] dateiNamen = dateiliste(exchange);
U 461     copyOrMoveFiles(quelle, ziel, dateiNamen, op, exchange);
462     standardHeaderUndAntwort(exchange, SC_OK, "Dateien verarbeitet.");
463   }
464
465   private String copyOrMoveFiles(String fromPath, String toPath, String[] fileNames, int operation, HttpExchange e) throws IOException {
466     String result = null;
467     File srcDir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), fromPath);
468     File targetDir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), toPath);
469     for (String fileName : fileNames) {
470       File srcFile = new File(srcDir, fileName);
5adf10 471       //logger.fine("srcFile: " + srcFile);
7fdd7e 472       if (srcFile.isDirectory()) {
5adf10 473         //logger.fine("srcFile is directory.");
7fdd7e 474         OrdnerBearbeiter bearbeiter = new OrdnerBearbeiter();
U 475         bearbeiter.setTargetDir(targetDir.toPath());
476         bearbeiter.setOperation(operation);
477         Files.walkFileTree(srcFile.toPath(), bearbeiter);
478       } else {
479         Path source = srcFile.toPath();
480         File destFile = targetDir.toPath().resolve(source.getFileName()).toFile();
481         if (destFile.exists()) {
482           FileTransporter trans = new FileTransporter();
483           destFile = trans.getNewFileName(destFile);
484         }
485         if (operation == OP_MOVE) {
486           String fname = srcFile.getName().toLowerCase();
487           if (fname.endsWith(ImageActor.JPEG)
488                   || fname.endsWith(ImageActor.JPG)
489                   || fname.endsWith(ImageActor.PNG)) {
490             moveImgFilesToDirectory(srcFile, srcDir, targetDir, false);
491           } else {
492             Files.move(source, destFile.toPath());
493           }
494         } else {
495           Files.copy(source, destFile.toPath());
496         }
497       }
498     }
499     return result;
500   }
501
502   private void loeschen(HttpExchange exchange, HttpHelper helper) throws IOException {
503     String[] dateiNamen = dateiliste(exchange);
504     String relPfad = helper.getFileName(exchange);
505     deleteFiles(relPfad, Arrays.asList(dateiNamen), exchange);
506     standardHeaderUndAntwort(exchange, SC_OK, "Dateien geloescht.");
507   }
508
509   private String[] dateiliste(HttpExchange exchange) throws IOException {
510     String body = new HttpHelper().bodyLesen(exchange);
5adf10 511     //logger.fine("dateien: " + body);
7fdd7e 512     Gson gson = new Gson();
U 513     return gson.fromJson(body, String[].class);
514   }
515
516   public String duplizieren(HttpExchange exchange, HttpHelper helper) throws IOException {
517     String relPfad = helper.getFileName(exchange);
518     File srcFile = new File(exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), relPfad);
519     String fnameext = srcFile.getName();
520     int dotpos = fnameext.lastIndexOf(STR_DOT);
521     String fname = fnameext.substring(0, dotpos);
522     String ext = fnameext.substring(dotpos);
523     File srcDir = srcFile.getParentFile();
524     File destFile = new File(srcDir, fname + "-Kopie" + ext);
525     int i = 1;
526     while (destFile.exists()) {
527       destFile = new File(srcDir, fname + "-Kopie-" + Integer.toString(++i) + ext);
528     }
529     Files.copy(srcFile.toPath(), destFile.toPath());
530     return destFile.getName();
531   }
532
533   public String umbenennen(HttpExchange exchange, HttpHelper helper, String neuerName) throws IOException {
534     File neueDatei;
535     String relPfad = helper.getFileName(exchange);
536     File file = new File(exchange.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), relPfad);
537     String fname = file.getName().toLowerCase();
538     if(fname.endsWith(ImageActor.JPEG) || fname.endsWith(ImageActor.JPG) || fname.endsWith(ImageActor.PNG)) {
539       neueDatei = renameImgFiles(file.getParentFile(), file, neuerName);  
540     } else {
541       neueDatei = new File(file.getParentFile(), neuerName);
542       file.renameTo(neueDatei);
543     }
544     return neueDatei.getName();
545   }
546   
547   public File renameImgFiles(File targetDir, File targetFile, String newName) throws IOException {
548     String alt;
549     String neu;
550     File neueDatei = targetFile;
551     
552     int newdotpos = newName.lastIndexOf(STR_DOT);
553     String newfname = newName.substring(0, newdotpos);
554     String newext = newName.substring(newdotpos);
5adf10 555     //logger.fine("newfname: " + newfname + ", newext: " + newext);
7fdd7e 556     
U 557     String fnameext = targetFile.getName();
558     int dotpos = fnameext.lastIndexOf(STR_DOT);
559     String fname = fnameext.substring(0, dotpos);
560     String ext = fnameext.substring(dotpos);
5adf10 561     //logger.fine("fname: " + fname + ", ext: " + ext);
7fdd7e 562     
U 563     DirectoryStream<Path> stream = Files.newDirectoryStream(targetDir.toPath(), fname + "*" + ext); //"*.{txt,doc,pdf,ppt}"
564     for (Path path : stream) {
5adf10 565       //logger.fine(path.getFileName().toString());
7fdd7e 566       alt = path.getFileName().toString();
5adf10 567       //logger.fine("alt: " + alt);
7fdd7e 568       if(alt.contains(ImageActor.TN)) {
U 569         neu = newfname + ImageActor.TN + newext;
570       } else if (alt.contains(ImageActor.KL)) {
571         neu = newfname + ImageActor.KL + newext;
572       } else if(alt.contains(ImageActor.GR)) {
573         neu = newfname + ImageActor.GR + newext;
574       } else if(alt.contains(ImageActor.MT)) {
575         neu = newfname + ImageActor.MT + newext;
576       } else if(alt.contains(ImageActor.SM)) {
577         neu = newfname + ImageActor.SM + newext;
578       } else {
579         neu = newName;
580       }
581       neueDatei = new File(targetDir, neu);
582       path.toFile().renameTo(neueDatei);              
583     }
584     stream.close();
585     return neueDatei;
586   }
587   
588   
589   private String deleteFiles(String relPath, List<String> fileNames, HttpExchange e) {
590     String result = null;
591     try {
5adf10 592       //logger.fine(fileNames.toString());
7fdd7e 593       if (!relPath.startsWith(STR_DOT)) {
U 594         File targetDir = new File(e.getHttpContext().getAttributes().get(FileHandler.ATTR_FILE_BASE).toString(), relPath); // getTargetDir(relPath);
5adf10 595         //logger.fine("targetDir: " + targetDir);
7fdd7e 596         for (String fileName : fileNames) {
U 597           File targetFile = new File(targetDir, fileName);
5adf10 598           //logger.fine(targetFile.getAbsolutePath());
7fdd7e 599           if (targetFile.isDirectory()) {
U 600             OrdnerBearbeiter bearbeiter = new OrdnerBearbeiter();
601             bearbeiter.setOperation(OP_DELETE);
602             Files.walkFileTree(targetFile.toPath(), bearbeiter);
603           } else {
604             /*
605                 Wenn targetFile mit jpg, jpeg oder png endet, 
606                 muss eine Unterfunktion eine Liste aller Dateien bilden, 
607                 die so heissen, also z.B. alle [Dateiname]*.jpg
608              */
609             String fname = targetFile.getName().toLowerCase();
610             if (fname.endsWith(ImageActor.JPEG)
611                     || fname.endsWith(ImageActor.JPG)
612                     || fname.endsWith(ImageActor.PNG)) {
613               deleteImgFiles(targetDir, targetFile);
614             } else {
615               targetFile.delete();
616             }
617           }
618         }
619         result = "deleted";
620       }
621     } catch (Throwable ex) {
5adf10 622       //logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
7fdd7e 623     }
U 624     return result;
625   }
626
627   private void deleteImgFiles(File targetDir, File targetFile) throws IOException {
628     String fnameext = targetFile.getName();
629     int dotpos = fnameext.lastIndexOf(STR_DOT);
630     String fname = fnameext.substring(0, dotpos);
631     String ext = fnameext.substring(dotpos);
5adf10 632     //logger.fine("fname: " + fname + ", ext: " + ext);
7fdd7e 633     DirectoryStream<Path> stream = Files.newDirectoryStream(targetDir.toPath(), fname + "*" + ext); //"*.{txt,doc,pdf,ppt}"
U 634     for (Path path : stream) {
5adf10 635       //logger.fine(path.getFileName().toString());
7fdd7e 636       Files.delete(path);
U 637     }
638     stream.close();
639   }
640
641   private void moveImgFilesToDirectory(File srcFile, File srcDir, File targetDir, boolean createDestDir) throws IOException {
642     String fnameext = srcFile.getName();
643     int dotpos = fnameext.lastIndexOf(STR_DOT);
644     String fname = fnameext.substring(0, dotpos);
645     String ext = fnameext.substring(dotpos);
5adf10 646     //logger.fine("fname: " + fname + ", ext: " + ext);
7fdd7e 647     Path targetPath = targetDir.toPath();
U 648     DirectoryStream<Path> stream = Files.newDirectoryStream(srcDir.toPath(), fname + "*" + ext); //"*.{txt,doc,pdf,ppt}"
649     for (Path path : stream) {
5adf10 650       //logger.fine(path.getFileName().toString());
7fdd7e 651       //Files.delete(path);
U 652       Files.move(path, targetPath.resolve(path.getFileName()));
653     }
654     stream.close();
655   }
656   
657   private void standardHeaderUndAntwort(HttpExchange exchange, int status, String antwort) throws IOException {
658     Headers resHeaders = exchange.getResponseHeaders();
659     resHeaders.add(CONTENT_TYPE, HttpHelper.CT_TEXT_HTML);
660     new HttpResponder().antwortSenden(exchange, status, antwort);
661   }  
662   
663
664   
665   
666 }