WebBox Klassenbibliothek
ulrich
2021-01-28 96dfd62fbfe771616045a253bbeb1415538e815f
commit | author | age
c583a8 1
U 2 package de.uhilger.wbx.web;
3
0b6a2b 4 import de.uhilger.wbx.WbxUtils;
c583a8 5 import de.vogella.rss.model.Feed;
U 6 import de.vogella.rss.model.FeedMessage;
7 import java.io.File;
8 import java.io.FileReader;
9 import java.io.IOException;
10 import java.io.Reader;
11 import java.text.SimpleDateFormat;
12 import java.util.ArrayList;
13 import java.util.Calendar;
14 import java.util.Date;
15 import java.util.GregorianCalendar;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Locale;
19 import java.util.logging.Level;
20 import java.util.logging.Logger;
21 import javax.servlet.ServletException;
22 import javax.servlet.ServletOutputStream;
23 import javax.servlet.http.HttpServlet;
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse;
26
27 /**
320c6e 28  * <p>Das FeedServlet erstellt Feeds von Ordnern der WebBox</p>
c583a8 29  * 
320c6e 30  * <p>Annahmen:</p>
U 31  * <ul>
32  * <li>Der JNDI-Parameter <code>wbxFileBase</code> enthaelt den absoluten Pfad 
33  * zur Dateiablage</li>
34  * <li>Der Parameter 'wbxPubDir' enthaelt den Namen des Ordners mit 
35  * oeffentlichen Inhalten und dieser Ordner liegt direkt unterhalb von 
36  * <code>wbxFileBase</code></li>
37  * <li>Der Ordner mit dem oeffentlichen Inhalt wird von Tomcat als Context 
38  * 1:1 ausgeliefert sodass bei einem URL wie 
39  * <code>http://example.com/[Context]/weitere/pfad/angaben/datei.html</code> 
40  * die Pfadangabe hinter <code>[Context]/</code> die Inhalte innerhalb von 
41  * <code>wbxFileBase/wbxPubDir</code> 1:1 wiedergibt.</li>
c583a8 42  * 
320c6e 43  * <p>Der JNDI-Parameter <code>wbxMaxFeedDepth</code> regelt, wie viele Ebenen der 
U 44  * Ordnerstruktur maximal nach Eintraegen durchsucht werden. Dabei haben die 
45  * tiefsten Ebenen Vorrang vor hoeher gelegenen Ebenen, d.h. Dateien auf 
46  * tieferen Ebenen werden vor Dateien auf hoeheren Ebenen in den Feed 
47  * aufgenommen.</p>
48  * 
49  * <p>Der JNDI-Parameter <code>wbxMaxFeedEntries</code> regelt, wie viele Beitraege 
50  * maximal im Feed erscheinen. Der Standardwert ist fuenf Beitraege, d.h., die 
51  * ersten fuenf gefundenen Beitraege werden chronologisch absteigend sortiert 
52  * nach ihrem letzten Aenderungsdatum ausgegeben.</p>
53  * 
54  * <p>Die Datei <code>CATALINA_BASE/conf/context.xml</code> muss also die 
55  * folgenden Eintraege enthalten:</p>
56  * <pre>
57  * <Environment name="wbxFileBase" type="java.lang.String" value="absoluter/pfad/zur/dateiablage" override="false" />
708f66 58  * <Environment name="wbxPubDirName" type="java.lang.String" value="/www" override="false" />
320c6e 59  * <Environment name="wbxFeedTitle" type="java.lang.String" value="Newsfeed" override="false" />
U 60  * <Environment name="wbxFeedSubtitle" type="java.lang.String" value="Text des Untertitels" override="false" />
61  * <Environment name="wbxFeedCopyright" type="java.lang.String" value="Text des Copyright-Hinweises" override="false" />
62  * <Environment name="wbxFeedDomain" type="java.lang.String" value="http://example.com" override="false" />
63  * <Environment name="wbxFeedAuthor" type="java.lang.String" value="Name des Autors" override="false" />
64  * </pre>
c583a8 65  */
U 66 public class FeedServlet extends HttpServlet {
67   
68   private static final Logger logger = Logger.getLogger(FeedServlet.class.getName());
69   
708f66 70   //public static final String JNDI_CTX_NAME = "java:comp/env";
U 71   //public static final String WBX_FILE_BASE = "wbxFileBase";
72   //public static final String WBX_PUB_DIR = "wbxPubDir";
c583a8 73   public static final String WBX_MAX_FEED_DEPTH = "wbxMaxFeedDepth";
U 74   public static final String WBX_MAX_FEED_ENTRIES = "wbxMaxFeedEntries";
320c6e 75   public static final String WBX_FEED_TITLE = "wbxFeedTitle";
U 76   public static final String WBX_FEED_SUBTITLE = "wbxFeedSubtitle";
77   public static final String WBX_FEED_COPYRIGHT = "wbxFeedCopyright";
78   public static final String WBX_FEED_DOMAIN = "wbxFeedDomain";
79   public static final String WBX_FEED_AUTHOR = "wbxFeedAuthor";
c583a8 80   
U 81   public static final int WBX_DEF_MAX_FEED_DEPTH = 3;
82   public static final int WBX_DEF_MAX_FEED_ENTRIES = 5;
0b6a2b 83     
c583a8 84   @Override
U 85   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
86     ServletOutputStream out = response.getOutputStream();
87     response.setContentType("text/xml");
88     String url = request.getRequestURL().toString();
89     logger.fine("requestURL: " + url);
320c6e 90     String contextPath = request.getContextPath();
U 91     logger.fine("contextPath: " + contextPath);
92     String zielPfad = url.substring(url.indexOf(contextPath));
c583a8 93     logger.fine(zielPfad);
0b6a2b 94     WbxUtils wu = new WbxUtils();
708f66 95     String basis = wu.getJNDIParameter(WbxUtils.WBX_FILE_BASE, WbxUtils.EMPTY_STRING);
320c6e 96     logger.fine("basis: " + basis);
882cad 97     if(basis.equals(WbxUtils.EMPTY_STRING)) {
U 98       basis = wu.getWbxDataDir().getAbsolutePath();
99     }
320c6e 100     StringBuffer pfad = new StringBuffer();
U 101     pfad.append(basis);
708f66 102     pfad.append(zielPfad.replace(contextPath, wu.getJNDIParameter(WbxUtils.WBX_PUB_DIR_NAME, WbxUtils.WBX_DEFAULT_PUB_DIR_NAME)));
320c6e 103     logger.fine("pfad: " + pfad);
U 104     String dirStr = pfad.toString().substring(0, pfad.lastIndexOf("/"));
105     logger.fine("dirStr: " + dirStr);
106     File dir = new File(dirStr);
107     if (dir.isDirectory()) {
108       List beitraege = new ArrayList();
0b6a2b 109       int maxBeitraege = wu.getJNDIInt(WBX_MAX_FEED_ENTRIES, WBX_DEF_MAX_FEED_ENTRIES);
U 110       int maxTiefe = wu.getJNDIInt(WBX_MAX_FEED_DEPTH, WBX_DEF_MAX_FEED_DEPTH);
96d8cf 111       wu.collectFiles(dir, 0, beitraege, maxTiefe, maxBeitraege);
320c6e 112       Iterator i = beitraege.iterator();
U 113       while (i.hasNext()) {
114         File f = (File) i.next();
115         logger.fine(f.getAbsolutePath() + " " + f.lastModified());
c583a8 116       }
0b6a2b 117       writeFeed(wu.getJNDIParameter(WBX_FEED_TITLE, WbxUtils.EMPTY_STRING), 
U 118               wu.getJNDIParameter(WBX_FEED_SUBTITLE, WbxUtils.EMPTY_STRING), out, beitraege, 
119               basis, pfad.toString(), contextPath, wu);
320c6e 120     } else {
U 121       logger.fine(dir.getAbsolutePath() + " ist kein Ordner.");
122     }
c583a8 123   }
96d8cf 124     
320c6e 125   public void writeFeed(String feedTitel, String beschr, ServletOutputStream s, 
0b6a2b 126           List beitraege, String basis, String pfad, String contextPath, WbxUtils wu) {
3e81ec 127     
U 128     long newest = -1;
0b6a2b 129     String copyright = wu.getJNDIParameter(WBX_FEED_COPYRIGHT, WbxUtils.EMPTY_STRING);
U 130     String domain = wu.getJNDIParameter(WBX_FEED_DOMAIN, WbxUtils.EMPTY_STRING);
c583a8 131     String title = feedTitel;
U 132     String description = beschr;
133     String language = "de";
320c6e 134     String link = domain;
3e81ec 135     
U 136     newest = ((File) beitraege.get(0)).lastModified();
137     
c583a8 138     Calendar cal = new GregorianCalendar();
3e81ec 139     cal.setTime(new Date(newest));
c583a8 140     Date creationDate = cal.getTime();
U 141     SimpleDateFormat date_format = new SimpleDateFormat(
142             "EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.US);
143     String pubdate = date_format.format(creationDate);
144     Feed rssFeed = new Feed(title, link, description, language,
145             copyright, pubdate);
146
147     Iterator i = beitraege.iterator();
148     while (i.hasNext()) {
149       File f = (File) i.next();
150       FeedMessage feedEintrag = new FeedMessage();
151       feedEintrag.setTitle(f.getName());
152       //feedEintrag.setDescription("Beschreibung hier");
0b6a2b 153       feedEintrag.setAuthor(wu.getJNDIParameter(WBX_FEED_AUTHOR, WbxUtils.EMPTY_STRING));
c583a8 154
U 155       String urlStr = f.getAbsolutePath();
320c6e 156       urlStr = urlStr.replace(basis, domain);
708f66 157       urlStr = urlStr.replace(wu.getJNDIParameter(WbxUtils.WBX_PUB_DIR_NAME, WbxUtils.WBX_DEFAULT_PUB_DIR_NAME), contextPath);
c583a8 158
U 159       logger.fine(urlStr);
160
161       feedEintrag.setGuid(urlStr);
162       feedEintrag.setLink(urlStr);
163       logger.fine(f.getName());
164       feedEintrag.setDescription(readFilePart(f, urlStr));
165       rssFeed.getMessages().add(feedEintrag);
166     }
167
168     FeedStreamWriter writer = new FeedStreamWriter(rssFeed, s);
169     try {
170       writer.write();
171     } catch (Exception e) {
172       logger.log(Level.SEVERE, e.getMessage(), e);
173     }
174   }
175   
176   private String readFilePart(File f, String urlStr) {
177     StringBuffer buf = new StringBuffer();
178     Reader reader = null;
179     try {
180       String fn = f.getName().toLowerCase();
181       if(fn.endsWith(".jpg") || fn.endsWith(".jpeg") || fn.endsWith(".png")) {
182         String noExt;
183         String ext;
184         int dotpos = urlStr.lastIndexOf('.');
185         if(dotpos > -1) {
186           noExt = urlStr.substring(0, dotpos);
187           ext = urlStr.substring(dotpos);
188         } else {
189           noExt = "";
190           ext = "";
191         }
192         buf.append("<a href='");
193         buf.append(urlStr);
194         buf.append("'><img src='");
195         buf.append(noExt);
196         buf.append("_kl");
197         buf.append(ext);
198         buf.append("'></a>");
199       } else {
200         reader = new FileReader(f);
201         char[] readBuffer = new char[1024];
202         int charsRead = reader.read(readBuffer);
203         buf.append(readBuffer);
204         reader.close();
205       }
206       return buf.toString();
207     } catch (Exception ex) {
208       logger.log(Level.SEVERE, null, ex);
209       return buf.toString();
210     }
211   }
212   
213 }