WebBox Klassenbibliothek
ulrich
2021-01-28 96dfd62fbfe771616045a253bbeb1415538e815f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/*
    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 <http://www.gnu.org/licenses/>.
*/
 
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<Inhalt> 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);
    if(basis.equals(WbxUtils.EMPTY_STRING)) {
      basis = getWbxDataDir().getAbsolutePath();
    }    
    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());
      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) {
    logger.fine(dir.getAbsolutePath());
    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") || nm.endsWith(".md")) {
          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;
    }
  }  
}