/* Dateiverwaltung - File management in your browser Copyright (C) 2017 Ulrich Hilger, http://uhilger.de 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 . */ package de.uhilger.wbx; import de.uhilger.wbx.data.Inhalt; import java.io.File; import java.io.FileReader; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.ServletContext; /** * */ public class WbxUtils { private static final Logger logger = Logger.getLogger(WbxUtils.class.getName()); public static final String JNDI_CTX_NAME = "java:comp/env"; public static final String NOT_FOUND = " nicht gefunden"; public static final String NO_STRING = " ist kein String"; public static final String EMPTY_STRING = ""; public static final String WBX_FILE_BASE = "wbxFileBase"; public static final String WBX_PUB_DIR_NAME = "wbxPubDirName"; public static final String WBX_DEFAULT_PUB_DIR_NAME = "/www"; public static final String WBX_PUB_URL_NAME = "wbxPubUrlName"; public static final String WBX_DEFAULT_PUB_URL_NAME = "/data"; /** * Bei der WebBox ist das Datenverzeichnis relativ zum Verzeichnis * $CATALINA_BASE/webapps untergebracht. * Die Abfrage ServletContext.getRealPath * liefert das Verzeichnis des Context dieser Webanwendung, also * $CATALINA_BASE/webapps/file-cms * oder * $WBX/sys/base/webapps/file-cms * * Unter Windows z.B. * C:\Users\fred\Documents\srv\wbx\sys\base\webapps\file-cms * Unter Linux oder Mac OS z.B. * /home/fred/srv/wbx/sys/base/webapps/file-cms * * Das Datenverzeichis liegt dann auf * $WBX/daten * * Mit dem Verzeichnis des Context dieser Webanwendung ist das * Datenverzeichnis der WebBox hart kodierbar mit dieser Methode * * @return Verzeichnis 'daten' der WebBox */ public File getWbxDataDir() { File file = getWbxDir(); file = new File(file, "daten/"); logger.fine("WebBox Datenbasis: " + file.getAbsolutePath()); return file; } public File getWbxDir() { logger.fine("Catalina Base: " + System.getProperty("catalina.base")); File catalinaBase = new File(System.getProperty("catalina.base")); File wbxDir = catalinaBase.getParentFile().getParentFile(); return wbxDir; } public List collectFiles(String requestUrl, String contextPath, String relativePath, int maxTiefe, int maxAnzahl, int length) { Bild bild = new Bild(); //WbxUtils wu = new WbxUtils(); String basis = getJNDIParameter(WBX_FILE_BASE, WbxUtils.EMPTY_STRING); String pubDirName = getJNDIParameter(WbxUtils.WBX_PUB_DIR_NAME, WbxUtils.WBX_DEFAULT_PUB_DIR_NAME); String pubUrlName = getJNDIParameter(WbxUtils.WBX_PUB_URL_NAME, WbxUtils.WBX_DEFAULT_PUB_URL_NAME); String relPath = relativePath.replace(pubUrlName, pubDirName); String absPath = basis + relPath; ArrayList beitraege = new ArrayList(); ArrayList files = new ArrayList<>(); collectFiles(new File(absPath), 0, beitraege, maxTiefe, maxAnzahl); Iterator i = beitraege.iterator(); while(i.hasNext()) { File beitrag = (File) i.next(); Inhalt cont = new Inhalt(); cont.setMimetype(bild.getMimeType(beitrag)); cont.setIsDirectory(beitrag.isDirectory()); cont.setIsHidden(beitrag.isHidden()); cont.setLastModified(beitrag.lastModified()); cont.setLength(beitrag.length()); if(length > 0) { cont.setAbst(getFileContent(beitrag, length)); } /* den 'https://..'-Teil bis vor dem ContextPath ermitteln */ //String requestUrl = getRequest().getRequestURL().toString(); //String contextPath = getRequest().getContextPath(); int pos = requestUrl.indexOf(contextPath); /* den Teil des Pfades ermitteln, der zwischen dem ContextPath zum oeffentlichen Ordner und dem Dateiname steht */ String absolutePath = beitrag.getAbsolutePath(); absolutePath = absolutePath.replace(beitrag.getName(), ""); absolutePath = absolutePath.replace(pubDirName, ""); String part = relativePath.replace(pubUrlName, ""); int pos2 = absolutePath.indexOf(part); String mittelteil = absolutePath.substring(pos2); mittelteil = mittelteil.replace(part, ""); cont.setBase(requestUrl.substring(0, pos)); cont.setUrl(/*requestUrl.substring(0, pos) + "/data" + */ mittelteil + beitrag.getName()); files.add(cont); } return files; } private String getFileContent(File file, int len) { try { StringBuffer readBuffer = new StringBuffer(); char[] buf = new char[1]; FileReader fr = new FileReader(file); int bytesRead = fr.read(buf); int read = 0; while(bytesRead > -1 && read < len) { read += bytesRead; readBuffer.append(buf); bytesRead = fr.read(buf); } readBuffer.append(buf); fr.close(); logger.fine("read: " + read + ", readBuffer.len: " + readBuffer.length()); return readBuffer.toString(); } catch (Exception ex) { logger.log(Level.SEVERE, ex.getMessage(), ex); return EMPTY_STRING; } } /** * Diese Methode funktioniert nur, wenn entweder ein Ordner uebergeben * wird, der keine Unterordner enthaelt wie zum Beispiel der Ordner 'neu' * der Bildersammlung oder ein Ordner, dessen Unterordner * nach dem Schema Jahr, Monat benannt sind wie bei einem Journal, das * die Beitraege wie folgt enthaelt: * Journal-Ordner * 2018 * 12 * 11 * 10 * usw. * 2017 * 12 * 11 * 10 * usw. * * @param out * @param dir * @param tiefe * @param dateizaehler */ public void collectFiles(File dir, int tiefe, List beitraege, int maxTiefe, int maxBeitraege) { List dirs = new ArrayList(); List beitraegeHier = new ArrayList(); File[] files = dir.listFiles(); for(int i = 0; i < files.length; i++) { if(files[i].isDirectory()) { if(tiefe < maxTiefe) { dirs.add(files[i]); } } else { beitraegeHier.add(files[i]); } } if(dirs.size() > 0) { // hier zuvor die Verzeichnissse absteigend nach Name sortieren Collections.sort(dirs, new Comparator() { @Override public int compare(File o1, File o2) { return o2.getName().compareTo(o1.getName()); } }); Iterator i = dirs.iterator(); while(i.hasNext() && beitraege.size() < maxBeitraege) { collectFiles((File) i.next(), tiefe+1, beitraege, maxTiefe, maxBeitraege); } } if(beitraegeHier.size() > 0) { // hier zuvor die Liste der Beitraege dieses Ordners nach lastModified absteigend sortieren // dann die neuesten in beitraege aufnehmen, bis die maximale Zahl gesuchter // neuer Beitraege erreicht ist. Collections.sort(beitraegeHier, new Comparator() { @Override public int compare(File o1, File o2) { int ergebnis; if(o1.lastModified() > o2.lastModified()) { ergebnis = -1; } else if(o2.lastModified() > o1.lastModified()) { ergebnis = 1; } else { ergebnis = 0; } return ergebnis; } }); Iterator i = beitraegeHier.iterator(); while(i.hasNext() && beitraege.size() < maxBeitraege) { File bf = (File) i.next(); String nm = bf.getName().toLowerCase(); if(nm.endsWith(".htmi") || nm.endsWith(".html") || nm.endsWith(".htm") || nm.endsWith(".jpg") || nm.endsWith(".jpeg") || nm.endsWith(".png") || nm.endsWith(".txt")) { beitraege.add(bf); } } } } public int getJNDIInt(String paramName, int defaultVal) { String jndiStr = getJNDIParameter(paramName, Integer.toString(defaultVal)); try { return Integer.parseInt(jndiStr); } catch(NumberFormatException ex) { logger.log(Level.FINE, ex.getMessage()); return defaultVal; } } public String getJNDIParameter(String pname, String defaultVal) { try { // unseren environment naming context ermitteln Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup(JNDI_CTX_NAME); // unseren Parameter lesen Object o = envCtx.lookup(pname); if(o instanceof String) { return o.toString(); } else { return defaultVal; } } catch (NamingException ex) { logger.log(Level.FINE, ex.getMessage()); return defaultVal; } } }