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