WebBox Klassenbibliothek
ulrich
2018-04-05 27d922ec03686599f688e8bb0a64375a3d559129
src/de/uhilger/wbx/WbxUtils.java
@@ -18,9 +18,23 @@
package de.uhilger.wbx;
import de.uhilger.wbx.data.Inhalt;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
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.servlet.ServletContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
/**
 *
@@ -29,36 +43,208 @@
  
  private static final Logger logger = Logger.getLogger(WbxUtils.class.getName());
  
  /**
   * 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 static File getWbxDataDir(ServletContext ctx) {
    String path = ctx.getRealPath("/");
    logger.fine("getRealPath: " + path); // file-cms in webapps
    File file = new File(path);
    file = file.getParentFile().getParentFile().getParentFile().getParentFile();
    file = new File(file, "daten/");
    logger.fine("Basis: " + file.getAbsolutePath());
    return file;
  }
  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";
  public List<Inhalt> collectFiles(String requestUrl, String contextPath,
          String relativePath, int maxTiefe, int maxAnzahl, long 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<Inhalt> 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());
      /*
        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, long len) {
    try {
      StringBuffer readBuffer = new StringBuffer();
      byte[] buf = new byte[1024];
      long read = 0;
      FileInputStream fis = new FileInputStream(file);
      int bytesRead = fis.read(buf);
      read += bytesRead;
      while(read < len) {
        readBuffer.append(buf);
        bytesRead = fis.read(buf);
        read += bytesRead;
      }
      readBuffer.append(buf);
      return readBuffer.toString();
    } catch (Exception ex) {
      Logger.getLogger(WbxUtils.class.getName()).log(Level.SEVERE, null, 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<File>() {
        @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<File>() {
        @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;
    }
  }
}