WebBox Klassenbibliothek
ulrich
2018-04-01 c583a8cfee9cc3f49029f69b23692577ba99eb68
Feed-Servlet hinzugefuegt
5 files added
681 ■■■■■ changed files
src/de/uhilger/wbx/web/FeedServlet.java 293 ●●●●● patch | view | raw | blame | history
src/de/uhilger/wbx/web/FeedStreamWriter.java 119 ●●●●● patch | view | raw | blame | history
src/de/uhilger/wbx/web/TestServlet.java 143 ●●●●● patch | view | raw | blame | history
src/de/vogella/rss/model/Feed.java 65 ●●●●● patch | view | raw | blame | history
src/de/vogella/rss/model/FeedMessage.java 61 ●●●●● patch | view | raw | blame | history
src/de/uhilger/wbx/web/FeedServlet.java
New file
@@ -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;
    }
  }
}
src/de/uhilger/wbx/web/FeedStreamWriter.java
New file
@@ -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);
    }
}
src/de/uhilger/wbx/web/TestServlet.java
New file
@@ -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>
}
src/de/vogella/rss/model/Feed.java
New file
@@ -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 + "]";
    }
}
src/de/vogella/rss/model/FeedMessage.java
New file
@@ -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
                + "]";
    }
}