From c583a8cfee9cc3f49029f69b23692577ba99eb68 Mon Sep 17 00:00:00 2001
From: ulrich <undisclosed>
Date: Sun, 01 Apr 2018 10:57:18 +0000
Subject: [PATCH] Feed-Servlet hinzugefuegt

---
 src/de/vogella/rss/model/FeedMessage.java    |   61 +++++
 src/de/uhilger/wbx/web/FeedStreamWriter.java |  119 +++++++++
 src/de/vogella/rss/model/Feed.java           |   65 +++++
 src/de/uhilger/wbx/web/FeedServlet.java      |  293 ++++++++++++++++++++++++
 src/de/uhilger/wbx/web/TestServlet.java      |  143 +++++++++++
 5 files changed, 681 insertions(+), 0 deletions(-)

diff --git a/src/de/uhilger/wbx/web/FeedServlet.java b/src/de/uhilger/wbx/web/FeedServlet.java
new file mode 100644
index 0000000..07d132a
--- /dev/null
+++ b/src/de/uhilger/wbx/web/FeedServlet.java
@@ -0,0 +1,293 @@
+
+package de.uhilger.wbx.web;
+
+import de.uhilger.wbx.web.FeedStreamWriter;
+import de.vogella.rss.model.Feed;
+import de.vogella.rss.model.FeedMessage;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+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;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Das FeedServlet erstellt Feeds von Ordnern der WebBox
+ * 
+ * Eine Maximaltiefe als Parameter soll regeln, wie viele Ordner tief 
+ * Dateien gesucht werden
+ * 
+ */
+public class FeedServlet extends HttpServlet {
+  
+  private static final Logger logger = Logger.getLogger(FeedServlet.class.getName());
+  
+  public static final String JNDI_CTX_NAME = "java:comp/env";
+  public static final String WBX_FILE_BASE = "wbxFileBase";
+  public static final String WBX_MAX_FEED_DEPTH = "wbxMaxFeedDepth";
+  public static final String WBX_MAX_FEED_ENTRIES = "wbxMaxFeedEntries";
+  
+  public static final int WBX_DEF_MAX_FEED_DEPTH = 3;
+  public static final int WBX_DEF_MAX_FEED_ENTRIES = 5;
+  
+  public static final String NOT_FOUND = " nicht gefunden";
+  public static final String NO_STRING = " ist kein String";  
+  
+  @Override
+  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+    ServletOutputStream out = response.getOutputStream();
+    response.setContentType("text/xml");
+    String url = request.getRequestURL().toString();
+    logger.fine("requestURL: " + url);
+    String dataUrl = url.replace("feed/", "data/");
+    logger.fine("dataUrl: " + dataUrl);
+    int pos = dataUrl.indexOf("data/");
+    String zielPfad = dataUrl.substring(pos);
+    logger.fine(zielPfad);
+    //ServletContext ctx = request.getServletContext();
+    //Object o = ctx.getAttribute(FILE_BASE);
+    String basis = getJNDIParameter(WBX_FILE_BASE);
+    //if(o instanceof String) {
+      //String basis = o.toString();
+      logger.fine("basis: " + basis);
+      StringBuffer pfad = new StringBuffer();
+      pfad.append(basis);
+      pfad.append(zielPfad.replace("data/", "/www/"));
+      logger.fine("pfad: " + pfad);
+      String dirStr = pfad.toString().substring(0, pfad.lastIndexOf("/"));
+      logger.fine("dirStr: " + dirStr);
+      File dir = new File(dirStr);
+      if(dir.isDirectory()) {
+        List beitraege = new ArrayList();
+        int maxBeitraege = getJNDIInt(WBX_MAX_FEED_ENTRIES, WBX_DEF_MAX_FEED_ENTRIES);
+        int maxTiefe = getJNDIInt(WBX_MAX_FEED_DEPTH, WBX_DEF_MAX_FEED_DEPTH);
+        collectFiles(dir, 0, beitraege, maxTiefe, maxBeitraege);
+        Iterator i = beitraege.iterator();
+        while(i.hasNext()) {
+          File f = (File) i.next();
+          logger.fine(f.getAbsolutePath() + " " + f.lastModified());
+        }
+        writeFeed("Newsfeed", "Neueste Inhalte von Ulrich Hilger", out, beitraege, basis, pfad.toString());
+      } else {
+        logger.fine(dir.getAbsolutePath() + " ist kein Ordner.");
+      }
+    //}    
+  }
+  
+  /**
+   * 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 
+   */
+  private 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 void writeFeed(String feedTitel, String beschr, ServletOutputStream s, List beitraege, String basis, String pfad) {
+    String copyright = "Copyright (c) 2018 Ulrich Hilger";
+    String title = feedTitel;
+    String description = beschr;
+    String language = "de";
+    String link = "https://www.uhilger.de";
+    Calendar cal = new GregorianCalendar();
+    Date creationDate = cal.getTime();
+    SimpleDateFormat date_format = new SimpleDateFormat(
+            "EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.US);
+    String pubdate = date_format.format(creationDate);
+    Feed rssFeed = new Feed(title, link, description, language,
+            copyright, pubdate);
+
+    Iterator i = beitraege.iterator();
+    while (i.hasNext()) {
+      File f = (File) i.next();
+      FeedMessage feedEintrag = new FeedMessage();
+      feedEintrag.setTitle(f.getName());
+      //feedEintrag.setDescription("Beschreibung hier");
+      feedEintrag.setAuthor("ulrich Punkt hilger bei web Punkt de (Ulrich Hilger)");
+
+      String urlStr = f.getAbsolutePath();
+      urlStr = urlStr.replace(basis, "https://uhilger.de");
+      urlStr = urlStr.replace("www/", "data/");
+
+      logger.fine(urlStr);
+
+      feedEintrag.setGuid(urlStr);
+      feedEintrag.setLink(urlStr);
+      logger.fine(f.getName());
+      feedEintrag.setDescription(readFilePart(f, urlStr));
+      rssFeed.getMessages().add(feedEintrag);
+    }
+
+    FeedStreamWriter writer = new FeedStreamWriter(rssFeed, s);
+    //RSSFeedWriter writer = new RSSFeedWriter(rssFeed, pfad + "/articles.rss");
+    //ByteArrayOutputStream bs = new ByteArrayOutputStream();
+    //RSSByteFeedWriter wr = new RSSByteFeedWriter(rssFeed, bs);
+    try {
+      writer.write();
+      //s.print(bs.toString());
+    } catch (Exception e) {
+      logger.log(Level.SEVERE, e.getMessage(), e);
+    }
+  }
+  
+  private String readFilePart(File f, String urlStr) {
+    StringBuffer buf = new StringBuffer();
+    Reader reader = null;
+    try {
+      String fn = f.getName().toLowerCase();
+      if(fn.endsWith(".jpg") || fn.endsWith(".jpeg") || fn.endsWith(".png")) {
+        String noExt;
+        String ext;
+        int dotpos = urlStr.lastIndexOf('.');
+        if(dotpos > -1) {
+          noExt = urlStr.substring(0, dotpos);
+          ext = urlStr.substring(dotpos);
+        } else {
+          noExt = "";
+          ext = "";
+        }
+        buf.append("<a href='");
+        buf.append(urlStr);
+        buf.append("'><img src='");
+        buf.append(noExt);
+        buf.append("_kl");
+        buf.append(ext);
+        buf.append("'></a>");
+      } else {
+        reader = new FileReader(f);
+        char[] readBuffer = new char[1024];
+        int charsRead = reader.read(readBuffer);
+        buf.append(readBuffer);
+        reader.close();
+      }
+      return buf.toString();
+    } catch (Exception ex) {
+      logger.log(Level.SEVERE, null, ex);
+      return buf.toString();
+    }
+  }
+  
+  private int getJNDIInt(String paramName, int defaultVal) {
+    String jndiStr = getJNDIParameter(paramName);
+    try {
+      return Integer.parseInt(jndiStr);
+    } catch(NumberFormatException ex) {
+      return defaultVal;
+    }
+  }
+  
+  private String getJNDIParameter(String pname) {
+    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 NO_STRING;
+      }
+    } catch (NamingException ex) {
+      logger.log(Level.SEVERE, ex.getMessage());
+      return NOT_FOUND;
+    }
+  }  
+  
+}
diff --git a/src/de/uhilger/wbx/web/FeedStreamWriter.java b/src/de/uhilger/wbx/web/FeedStreamWriter.java
new file mode 100644
index 0000000..6708c7b
--- /dev/null
+++ b/src/de/uhilger/wbx/web/FeedStreamWriter.java
@@ -0,0 +1,119 @@
+package de.uhilger.wbx.web;
+
+import java.io.FileOutputStream;
+
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartDocument;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+import de.vogella.rss.model.Feed;
+import de.vogella.rss.model.FeedMessage;
+import java.io.OutputStream;
+
+public class FeedStreamWriter {
+
+    //private String outputFile;
+    private Feed rssfeed;
+    private OutputStream out;
+
+    public FeedStreamWriter(Feed rssfeed, OutputStream s) {
+        this.rssfeed = rssfeed;
+        this.out = s;
+    }
+
+    public void write() throws Exception {
+
+        // create a XMLOutputFactory
+        XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
+
+        // create XMLEventWriter
+        XMLEventWriter eventWriter = outputFactory
+                .createXMLEventWriter(out);
+
+        // create a EventFactory
+
+        XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+        XMLEvent end = eventFactory.createDTD("\n");
+
+        // create and write Start Tag
+
+        StartDocument startDocument = eventFactory.createStartDocument();
+
+        eventWriter.add(startDocument);
+
+        // create open tag
+        eventWriter.add(end);
+
+        StartElement rssStart = eventFactory.createStartElement("", "", "rss");
+        eventWriter.add(rssStart);
+        eventWriter.add(eventFactory.createAttribute("version", "2.0"));
+        eventWriter.add(end);
+
+        eventWriter.add(eventFactory.createStartElement("", "", "channel"));
+        eventWriter.add(end);
+
+        // Write the different nodes
+
+        createNode(eventWriter, "title", rssfeed.getTitle());
+
+        createNode(eventWriter, "link", rssfeed.getLink());
+
+        createNode(eventWriter, "description", rssfeed.getDescription());
+
+        createNode(eventWriter, "language", rssfeed.getLanguage());
+
+        createNode(eventWriter, "copyright", rssfeed.getCopyright());
+
+        createNode(eventWriter, "pubdate", rssfeed.getPubDate());
+
+        for (FeedMessage entry : rssfeed.getMessages()) {
+            eventWriter.add(eventFactory.createStartElement("", "", "item"));
+            eventWriter.add(end);
+            createNode(eventWriter, "title", entry.getTitle());
+            createNode(eventWriter, "description", entry.getDescription());
+            createNode(eventWriter, "link", entry.getLink());
+            createNode(eventWriter, "author", entry.getAuthor());
+            createNode(eventWriter, "guid", entry.getGuid());
+            eventWriter.add(end);
+            eventWriter.add(eventFactory.createEndElement("", "", "item"));
+            eventWriter.add(end);
+
+        }
+
+        eventWriter.add(end);
+        eventWriter.add(eventFactory.createEndElement("", "", "channel"));
+        eventWriter.add(end);
+        eventWriter.add(eventFactory.createEndElement("", "", "rss"));
+
+        eventWriter.add(end);
+
+        eventWriter.add(eventFactory.createEndDocument());
+
+        eventWriter.close();
+    }
+
+    private void createNode(XMLEventWriter eventWriter, String name,
+
+    String value) throws XMLStreamException {
+        XMLEventFactory eventFactory = XMLEventFactory.newInstance();
+        XMLEvent end = eventFactory.createDTD("\n");
+        XMLEvent tab = eventFactory.createDTD("\t");
+        // create Start node
+        StartElement sElement = eventFactory.createStartElement("", "", name);
+        eventWriter.add(tab);
+        eventWriter.add(sElement);
+        // create Content
+        Characters characters = eventFactory.createCharacters(value);
+        eventWriter.add(characters);
+        // create End node
+        EndElement eElement = eventFactory.createEndElement("", "", name);
+        eventWriter.add(eElement);
+        eventWriter.add(end);
+    }
+}
\ No newline at end of file
diff --git a/src/de/uhilger/wbx/web/TestServlet.java b/src/de/uhilger/wbx/web/TestServlet.java
new file mode 100644
index 0000000..9580778
--- /dev/null
+++ b/src/de/uhilger/wbx/web/TestServlet.java
@@ -0,0 +1,143 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package de.uhilger.wbx.web;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+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;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ *
+ */
+public class TestServlet extends HttpServlet {
+  
+  private static final Logger logger = Logger.getLogger(TestServlet.class.getName());
+  
+  public static final String JNDI_CTX_NAME = "java:comp/env";
+  public static final String PARAM_NAME = "wbxFileBase";
+  public static final String NOT_FOUND = " nicht gefunden";
+  public static final String NO_STRING = " ist kein String";
+
+  /**
+   * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
+   * methods.
+   *
+   * @param request servlet request
+   * @param response servlet response
+   * @throws ServletException if a servlet-specific error occurs
+   * @throws IOException if an I/O error occurs
+   */
+  protected void processRequest(HttpServletRequest request, HttpServletResponse response)
+          throws ServletException, IOException {
+    response.setContentType("text/html;charset=UTF-8");
+    try (PrintWriter out = response.getWriter()) {
+      out.println("<!DOCTYPE html>");
+      out.println("<html>");
+      out.println("<head>");
+      out.println("<title>Servlet TestServlet</title>");   
+      out.println("</head>");
+      out.println("<body>");
+      out.println("<h1>Servlet TestServlet at " + request.getContextPath() + "</h1>");
+      
+      // hier kommt veraenderlicher Inhalt
+      ServletContext ctx = request.getServletContext();
+      Object o = ctx.getAttribute("filebase");
+      String base;
+      if(o instanceof String) {
+        base = o.toString();
+      } else {
+        base = "unbekannt";
+      }
+      out.print("<p>filebase: ");
+      out.print(base);
+      out.print("</p>\n");
+      
+      out.print("<p>");
+      out.print(PARAM_NAME);
+      out.print(": ");
+      out.print(getJNDIParameter(PARAM_NAME));
+      out.print("</p>\n");
+      
+      out.print("<p>");
+      out.print("Request URL: ");
+      out.print(request.getRequestURL());
+      out.print("</p>\n");
+      // Ende des veraenderlichen Inhalts
+      
+      out.println("</body>");
+      out.println("</html>");
+    }
+  }
+  
+ private String getJNDIParameter(String pname) {
+    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 NO_STRING;
+      }
+    } catch (NamingException ex) {
+      logger.log(Level.SEVERE, ex.getMessage());
+      return NOT_FOUND;
+    }
+  }  
+  
+
+  // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
+  /**
+   * Handles the HTTP <code>GET</code> method.
+   *
+   * @param request servlet request
+   * @param response servlet response
+   * @throws ServletException if a servlet-specific error occurs
+   * @throws IOException if an I/O error occurs
+   */
+  @Override
+  protected void doGet(HttpServletRequest request, HttpServletResponse response)
+          throws ServletException, IOException {
+    processRequest(request, response);
+  }
+
+  /**
+   * Handles the HTTP <code>POST</code> method.
+   *
+   * @param request servlet request
+   * @param response servlet response
+   * @throws ServletException if a servlet-specific error occurs
+   * @throws IOException if an I/O error occurs
+   */
+  @Override
+  protected void doPost(HttpServletRequest request, HttpServletResponse response)
+          throws ServletException, IOException {
+    processRequest(request, response);
+  }
+
+  /**
+   * Returns a short description of the servlet.
+   *
+   * @return a String containing servlet description
+   */
+  @Override
+  public String getServletInfo() {
+    return "Short description";
+  }// </editor-fold>
+
+}
diff --git a/src/de/vogella/rss/model/Feed.java b/src/de/vogella/rss/model/Feed.java
new file mode 100644
index 0000000..e124ee1
--- /dev/null
+++ b/src/de/vogella/rss/model/Feed.java
@@ -0,0 +1,65 @@
+package de.vogella.rss.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * Stores an RSS feed
+ */
+public class Feed {
+
+    final String title;
+    final String link;
+    final String description;
+    final String language;
+    final String copyright;
+    final String pubDate;
+
+    final List<FeedMessage> entries = new ArrayList<FeedMessage>();
+
+    public Feed(String title, String link, String description, String language,
+            String copyright, String pubDate) {
+        this.title = title;
+        this.link = link;
+        this.description = description;
+        this.language = language;
+        this.copyright = copyright;
+        this.pubDate = pubDate;
+    }
+
+    public List<FeedMessage> getMessages() {
+        return entries;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public String getLink() {
+        return link;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getLanguage() {
+        return language;
+    }
+
+    public String getCopyright() {
+        return copyright;
+    }
+
+    public String getPubDate() {
+        return pubDate;
+    }
+
+    @Override
+    public String toString() {
+        return "Feed [copyright=" + copyright + ", description=" + description
+                + ", language=" + language + ", link=" + link + ", pubDate="
+                + pubDate + ", title=" + title + "]";
+    }
+
+}
\ No newline at end of file
diff --git a/src/de/vogella/rss/model/FeedMessage.java b/src/de/vogella/rss/model/FeedMessage.java
new file mode 100644
index 0000000..6cb9b45
--- /dev/null
+++ b/src/de/vogella/rss/model/FeedMessage.java
@@ -0,0 +1,61 @@
+package de.vogella.rss.model;
+
+/*
+ * Represents one RSS message
+ */
+public class FeedMessage {
+
+    String title;
+    String description;
+    String link;
+    String author;
+    String guid;
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getLink() {
+        return link;
+    }
+
+    public void setLink(String link) {
+        this.link = link;
+    }
+
+    public String getAuthor() {
+        return author;
+    }
+
+    public void setAuthor(String author) {
+        this.author = author;
+    }
+
+    public String getGuid() {
+        return guid;
+    }
+
+    public void setGuid(String guid) {
+        this.guid = guid;
+    }
+
+    @Override
+    public String toString() {
+        return "FeedMessage [title=" + title + ", description=" + description
+                + ", link=" + link + ", author=" + author + ", guid=" + guid
+                + "]";
+    }
+
+}

--
Gitblit v1.9.3