Author: tchemit
Date: 2008-05-31 16:33:29 +0000 (Sat, 31 May 2008)
New Revision: 76
Added:
trunk/lutinrss/src/main/java/org/codelutin/rss/BaseServlet.java
trunk/lutinrss/src/main/java/org/codelutin/rss/ConfigInitializer.java
trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGenerator.java
trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorConfig.java
Removed:
trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorHelper.java
Modified:
trunk/lutinrss/src/main/java/org/codelutin/rss/RSSConfig.java
trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorServlet.java
trunk/lutinrss/src/main/java/org/codelutin/rss/RSSHelper.java
trunk/lutinrss/src/main/java/org/codelutin/rss/RSSIOUtil.java
trunk/lutinrss/src/main/java/org/codelutin/rss/RSSServlet.java
Log:
refactor RSSSevlet and RSSGeneratorServlet
Added: trunk/lutinrss/src/main/java/org/codelutin/rss/BaseServlet.java
===================================================================
--- trunk/lutinrss/src/main/java/org/codelutin/rss/BaseServlet.java (rev 0)
+++ trunk/lutinrss/src/main/java/org/codelutin/rss/BaseServlet.java 2008-05-31 16:33:29 UTC (rev 76)
@@ -0,0 +1,112 @@
+package org.codelutin.rss;
+
+import java.io.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * <p>
+ * Servlet de base
+ * @param D la classe de l'object de delegation
+ *
+ * @author chemit
+ */
+public abstract class BaseServlet<D> extends HttpServlet {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ protected static final Log log = LogFactory.getLog(BaseServlet.class);
+ /** L'objet de delegation du metier de la servlet */
+ protected transient D delegate;
+ private static final long serialVersionUID = 1L;
+
+ /**
+ *
+ * @return the new delegate object to be used by servlet
+ * @throws java.lang.Exception if any problem while instanciation
+ */
+ protected abstract D newDelegate() throws Exception;
+
+ /**
+ *
+ * @return a new ConfigInitializer to be used in
+ * {@link #init(javax.servlet.ServletConfig, boolean)} method to prepare
+ * default config.
+ */
+ protected abstract ConfigInitializer<ServletConfig,? > newConfigInitializer();
+
+ /**
+ * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
+ * @param request servlet request
+ * @param response servlet response
+ * @throws java.io.IOException TODO
+ * @throws ServletException TODO
+ */
+ protected abstract void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
+
+ @Override
+ public void init(ServletConfig config) throws ServletException {
+ init(config, true);
+ }
+
+ protected void init(ServletConfig config, boolean initConfig) throws ServletException {
+ try {
+ super.init(config);
+ if (initConfig) {
+ // init de la configuration par defaut depuis la config de servlet
+ newConfigInitializer().init(config);
+ }
+ // instanciate delegate
+ delegate = newDelegate();
+ } catch (Exception eee) {
+ log.warn("Can't configure Servlet", eee);
+ if (eee instanceof ServletException) {
+ throw (ServletException) eee;
+ }
+ throw new ServletException("Can't configure Servlet", eee);
+ }
+ }
+
+ protected Integer convertToInt(String parameter) {
+ Integer result = null;
+ try {
+ result = Integer.parseInt(parameter);
+ } catch (Exception eee) {
+ log.debug("Can't convert to int: '" + parameter + "'", eee);
+ }
+ return result;
+ }
+ // <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
+ */
+ @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
+ */
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ processRequest(request, response);
+ }
+
+ /**
+ * Returns a short description of the servlet.
+ */
+ @Override
+ public String getServletInfo() {
+ return "RSS Servlet";
+ }
+ // </editor-fold>
+}
Added: trunk/lutinrss/src/main/java/org/codelutin/rss/ConfigInitializer.java
===================================================================
--- trunk/lutinrss/src/main/java/org/codelutin/rss/ConfigInitializer.java (rev 0)
+++ trunk/lutinrss/src/main/java/org/codelutin/rss/ConfigInitializer.java 2008-05-31 16:33:29 UTC (rev 76)
@@ -0,0 +1,60 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.codelutin.rss;
+
+import org.apache.commons.beanutils.BeanUtils;
+
+/**
+ *
+ * @author tony
+ *
+ * @param S la classe source de la configuration
+ * @param T la classe destination de la configuration
+ */
+public abstract class ConfigInitializer<S,D> {
+
+
+ /**
+ *
+ * @param config l'object source contenant les configs
+ * @param fullConfigName le nom complet de la propriete recherchee
+ * @return la valeur de la propriete ou null si non trouve
+ */
+ protected abstract String getConfigValue(S config, String fullConfigName);
+
+ public abstract void init(S config) ;
+
+ /**
+ * Initialise RSSConfig.
+ * @param klass la class de la configuration de destination
+ * @param config la configuration source
+ */
+ public void init(String prefix,Class<D> klass, S config, String... keys) {
+ try {
+ String prefixConfig = getConfigValue(config, prefix);
+ prefixConfig = prefixConfig == null ? "" : prefixConfig.trim();
+
+ D instance = klass.newInstance();
+ for (String key : keys) {
+ loadConfig(config, instance, prefixConfig, key);
+ }
+ } catch (InstantiationException ex) {
+ throw new RuntimeException(ex);
+ } catch (IllegalAccessException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ protected void loadConfig(S config, D instance, String prefix, String configName) {
+ String value = getConfigValue(config, prefix + configName);
+ if (value != null && !"".equals(value)) {
+ try {
+ BeanUtils.setProperty(instance, configName, value);
+ } catch (Exception ex) {
+ throw new IllegalStateException("could not load property " + configName + " from config " + config + " for reason : " + ex.getMessage());
+ }
+ }
+ }
+}
Modified: trunk/lutinrss/src/main/java/org/codelutin/rss/RSSConfig.java
===================================================================
--- trunk/lutinrss/src/main/java/org/codelutin/rss/RSSConfig.java 2008-05-30 20:39:08 UTC (rev 75)
+++ trunk/lutinrss/src/main/java/org/codelutin/rss/RSSConfig.java 2008-05-31 16:33:29 UTC (rev 76)
@@ -1,10 +1,8 @@
package org.codelutin.rss;
-import java.io.File;
-import org.apache.commons.beanutils.BeanUtils;
-
/**
- *
+ * Default configuration for {@link RSSHelper}.
+ *
* @author poussin
*/
public class RSSConfig {
@@ -12,23 +10,14 @@
/**
* la propriete de configuration qui definit le prefix a jouter pour scruter la configuration
*/
- protected static final String CONFIGURATION_PREFIX_PROPERTY = RSSServlet.class.getSimpleName() + "_configuration_prefix";
+ private static final String CONFIGURATION_PREFIX_PROPERTY = RSSServlet.class.getSimpleName() + "_configuration_prefix";
+
/** Temps a partir duquel on reforce une recuperation */
public static long TIME_FORCE_RETRIEVED = 5 * 60 * 1000;
-
public static FeedRendererConfig DEFAULT_RENDERER_CONFIG = new FeedRendererConfig("n-natd");
-
- public static int DEFAULT_NB_ITEM = 7;
-
- public static int DEFAULT_GENERATOR_NB_ITEM = 100;
-
- public static FeedType DEFAULT_GENERATOR_FORMAT = FeedType.RSS_2_0;
-
- public static String GENERATOR_DIRECTORY = "/tmp/rssinclude";
-
+ public static int DEFAULT_NB_ITEM = 7;
public static Class<? extends FeedRenderer> DEFAULT_RENDERER_CLASS = FeedHTMLRenderer.class;
-
public static Class<? extends FeedURLResolver> DEFAULT_RESOLVER_CLASS = SimpleFeedURLResolver.class;
public void setTIME_FORCE_RETRIEVED(long TIME_FORCE_RETRIEVED) {
@@ -51,63 +40,24 @@
RSSConfig.DEFAULT_RESOLVER_CLASS = DEFAULT_RESOLVER_CLASS;
}
- public static void setDEFAULT_GENERATOR_NB_ITEM(int DEFAULT_GENERATOR_NB_ITEM) {
- RSSConfig.DEFAULT_GENERATOR_NB_ITEM = DEFAULT_GENERATOR_NB_ITEM;
- }
-
- public static void setDEFAULT_GENERATOR_FORMAT(FeedType DEFAULT_GENERATOR_FORMAT) {
- RSSConfig.DEFAULT_GENERATOR_FORMAT = DEFAULT_GENERATOR_FORMAT;
- }
-
- public static void setGENERATOR_DIRECTORY(String GENERATOR_DIRECTORY) {
- RSSConfig.GENERATOR_DIRECTORY = GENERATOR_DIRECTORY;
- }
-
-
/**
*
- * @param T la classe sources de la configuration
+ * @param S la classe source de la configuration
*/
- public static abstract class RSSConfigInitializer<T> {
+ public static abstract class RSSConfigInitializer<S> extends ConfigInitializer<S,RSSConfig > {
/**
- *
- * @param config l'object source contenant les configs
- * @param fullConfigName le nom complet de la propriete recherchee
- * @return la valeur de la propriete ou null si non trouve
- */
- protected abstract String getConfigValue(T config, String fullConfigName);
-
- /**
* Initialise RSSConfig.
- * @param config l'object de configuration
+ * @param config la configuration source
*/
- public void init(T config) {
- String prefixConfig = getConfigValue(config, CONFIGURATION_PREFIX_PROPERTY);
- prefixConfig = prefixConfig == null ? "" : prefixConfig.trim();
- RSSConfig instance = new RSSConfig();
- loadConfig(config, instance, prefixConfig, "TIME_FORCE_RETRIEVED");
- loadConfig(config, instance, prefixConfig, "DEFAULT_RENDERER_CONFIG");
- loadConfig(config, instance, prefixConfig, "DEFAULT_NB_ITEM");
- loadConfig(config, instance, prefixConfig, "DEFAULT_RENDERER_CLASS");
- loadConfig(config, instance, prefixConfig, "DEFAULT_RESOLVER_CLASS");
- loadConfig(config, instance, prefixConfig, "DEFAULT_GENERATOR_NB_ITEM");
- loadConfig(config, instance, prefixConfig, "DEFAULT_GENERATOR_FORMAT");
- loadConfig(config, instance, prefixConfig, "GENERATOR_DIRECTORY");
-
- // create generator directory
- new File(GENERATOR_DIRECTORY).mkdirs();
+ public void init(S config) {
+ RSSHelper.log.info("with source "+config);
+ super.init(CONFIGURATION_PREFIX_PROPERTY,RSSConfig.class, config,
+ "TIME_FORCE_RETRIEVED",
+ "DEFAULT_RENDERER_CONFIG",
+ "DEFAULT_NB_ITEM",
+ "DEFAULT_RENDERER_CLASS",
+ "DEFAULT_RESOLVER_CLASS");
}
-
- protected void loadConfig(T config, RSSConfig instance, String prefix, String configName) {
- String value = getConfigValue(config, prefix + configName);
- if (value != null && !"".equals(value)) {
- try {
- BeanUtils.setProperty(instance, configName, value);
- } catch (Exception ex) {
- throw new IllegalStateException("could not load property " + configName + " from config " + config + " for reason : " + ex.getMessage());
- }
- }
- }
}
}
Copied: trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGenerator.java (from rev 74, trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorHelper.java)
===================================================================
--- trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGenerator.java (rev 0)
+++ trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGenerator.java 2008-05-31 16:33:29 UTC (rev 76)
@@ -0,0 +1,242 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.codelutin.rss;
+
+import com.sun.syndication.feed.synd.SyndEntry;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.io.FeedException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.EnumMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * generator of rss feeds to be stored in a file
+ * @author tony
+ */
+public class RSSGenerator {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static final Log log = LogFactory.getLog(RSSGenerator.class);
+ /** date formater use to save date in feed and entries */
+ static final DateFormat DATE_PARSER = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
+
+ /**
+ *
+ * @return une nouvelle instance de RssHelper en utilisant les implantations
+ * definies dans RSSGeneratorConfig.
+ * @throws java.lang.Exception pour tout pb lors de l'instanciation des objects
+ */
+ public static RSSGenerator newDefaultInstance() throws Exception {
+ RSSGenerator helper = new RSSGenerator();
+ return helper;
+ }
+
+
+ /** dictonnary of field <-> property for feed */
+ protected final EnumMap<Field, String> feedProperties;
+ /** dictonnary of field <-> property for entry */
+ protected final EnumMap<Field, String> itemProperties;
+ /** directory where feeds are stored */
+ protected final File generatorDirectory;
+
+ protected RSSGenerator() {
+ this(null);
+ }
+
+ protected RSSGenerator(EnumMap<Field, String> feedProperties, EnumMap<Field, String> itemProperties, File generatorDirectory) {
+ this.feedProperties = feedProperties;
+ this.itemProperties = itemProperties;
+ this.generatorDirectory = generatorDirectory;
+ }
+
+ protected RSSGenerator(File generatorDirectory) {
+
+ feedProperties = new EnumMap<Field, String>(Field.class);
+ feedProperties.put(Field.NAME, "title");
+ feedProperties.put(Field.LINK, "link");
+ // cela engendre des NPE...
+ feedProperties.put(Field.IMAGE, "image.url");
+ feedProperties.put(Field.DESCRIPTION, "description");
+ feedProperties.put(Field.AUTHOR, "author");
+ feedProperties.put(Field.TIME, "publishedDate");
+
+ itemProperties = new EnumMap<Field, String>(Field.class);
+ itemProperties.put(Field.NAME, "title");
+ itemProperties.put(Field.LINK, "link");
+ itemProperties.put(Field.IMAGE, null);
+ itemProperties.put(Field.DESCRIPTION, "description.value");
+ itemProperties.put(Field.AUTHOR, "author");
+ itemProperties.put(Field.TIME, "publishedDate");
+
+ this.generatorDirectory = generatorDirectory==null?new File(RSSGeneratorConfig.GENERATOR_DIRECTORY):generatorDirectory;
+ }
+
+ /**
+ *
+ * @param url location where to create the file
+ * @param type fromat of feed to create
+ * @param values properties of the feed
+ * @throws ParseException if pb while parsing date
+ * @throws IOException if io pb
+ * @throws FeedException if pb while creating feed
+ */
+ public void createFeedFile(URL url, FeedType type, Map<Field, Object> values) throws IOException, FeedException, ParseException {
+ if (url == null) {
+ throw new NullPointerException("can not create a feed with null url");
+ }
+ if (type == null) {
+ throw new NullPointerException("can not create a feed with null feedtype");
+ }
+ if (values == null || values.isEmpty()) {
+ //TODO Should check mandatory values (title, link,...)
+ throw new NullPointerException("can not create a feed with null nor empty values dictonnary");
+ }
+ File f = getFile(url);
+
+ if (f.exists()) {
+ throw new IllegalStateException("feed already existing in " + f.getName());
+ }
+
+ // make sure parent exists
+ f.getParentFile().mkdirs();
+
+ // block until can acquire lock
+ FileLock lock = acquireLock(f);
+
+ try {
+
+ SyndFeed feed = RSSIOUtil.createFeed(feedProperties, type, values);
+
+ RSSIOUtil.saveFeed(f, feed);
+
+ } catch (FeedException e) {
+ // file must not be created
+ f.delete();
+ throw e;
+ } catch (ParseException e) {
+ // file must not be created
+ f.delete();
+ throw e;
+ } finally {
+ releaseLock(f, lock);
+ }
+ }
+
+ /**
+ * Add a item to an existing feed file.
+ *
+ * @param url location of feed to used
+ * @param nbEntries number of maximum entries to be written in feed file
+ * @param values dictionnary of properties to write
+ * @throws FeedException if feed pb
+ * @throws IOException if io pb
+ * @throws ParseException if dateparser pb
+ */
+ public void addItemToFeedFile(URL url, int nbEntries, Map<Field, Object> values) throws IOException, FeedException, ParseException {
+ if (url == null) {
+ throw new NullPointerException("can not add a feed's entry with null url");
+ }
+ if (values == null || values.isEmpty()) {
+ //TODO Should check mandatory values (title, link,...)
+ throw new NullPointerException("can not add a feed's entry with null nor empty values dictonnary");
+ }
+ File f = getFile(url);
+
+ if (!f.exists()) {
+ throw new FileNotFoundException("file not existing " + f);
+ }
+
+ // block until can acquire lock
+ FileLock lock = acquireLock(f);
+
+ try {
+ // get feed
+ SyndFeed feed = RSSIOUtil.readFeed(url);
+
+ // create item
+ SyndEntry item = RSSIOUtil.createFeedItem(itemProperties, values);
+
+ // add item
+ feed = RSSIOUtil.addItemToFeed(feed, item, nbEntries, values);
+
+ // save feed into a tmp file
+ File tmpFile = new File(f.getAbsolutePath() + "-tmp_" + System.nanoTime());
+
+ RSSIOUtil.saveFeed(tmpFile, feed);
+
+ // move tmpFile to real file
+ tmpFile.renameTo(f);
+ } finally {
+ releaseLock(f, lock);
+ }
+ }
+
+ public void deleteFeedFile(URL toURL) {
+ File f = getFile(toURL);
+ if (f.exists() && !f.delete()) {
+ throw new IllegalStateException("could not delete feed " + f.getName());
+ }
+ }
+
+ /**
+ * Obtain the file from his url location.
+ *
+ * @param url location of the file
+ * @return the file
+ * @throws java.lang.IllegalStateException if uri is not sytax valid
+ */
+ protected File getFile(URL url) throws IllegalStateException {
+ try {
+ return new File(url.toURI());
+ } catch (URISyntaxException e) {
+ throw new IllegalStateException("could not obtain file from url " + url, e);
+ }
+ }
+
+ protected FileLock acquireLock(File f) throws IOException {
+ File lockFile = getWriteFileLock(f);
+
+ /*if (!lockFile.exists()) lockFile.createNewFile(); */
+ // open file for writing only
+ FileChannel channel = new RandomAccessFile(lockFile, "rw").getChannel();
+
+ // block until can acquire lock
+
+ return channel.lock();
+ }
+
+ protected File getWriteFileLock(File f) {
+ return new File(f.getParentFile(), f.getName() + ".wlock");
+ }
+
+ protected void releaseLock(File f, FileLock lock) throws IOException {
+ // release lock
+ lock.release();
+ // close channel
+ lock.channel().close();
+ // delete file lock
+ File lockFile = getWriteFileLock(f);
+ // delete lock file
+ lockFile.delete();
+ }
+
+ public File getGeneratorDirectory() {
+ return generatorDirectory;
+ }
+
+}
Added: trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorConfig.java
===================================================================
--- trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorConfig.java (rev 0)
+++ trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorConfig.java 2008-05-31 16:33:29 UTC (rev 76)
@@ -0,0 +1,55 @@
+package org.codelutin.rss;
+
+/**
+ *
+ * Default Configuration for {@link RSSGenerator}.
+ *
+ * @author chemit
+ */
+public class RSSGeneratorConfig {
+
+ /**
+ * la propriete de configuration qui definit le prefix a jouter pour scruter la configuration
+ */
+ private static final String CONFIGURATION_PREFIX_PROPERTY = RSSGeneratorServlet.class.getSimpleName() + "_configuration_prefix";
+
+ public static int DEFAULT_GENERATOR_NB_ITEM = 100;
+ public static FeedType DEFAULT_GENERATOR_FORMAT = FeedType.RSS_2_0;
+ public static String GENERATOR_DIRECTORY = "/tmp/rssinclude";
+
+ public static void setDEFAULT_GENERATOR_NB_ITEM(int DEFAULT_GENERATOR_NB_ITEM) {
+ RSSGeneratorConfig.DEFAULT_GENERATOR_NB_ITEM = DEFAULT_GENERATOR_NB_ITEM;
+ }
+
+ public static void setDEFAULT_GENERATOR_FORMAT(FeedType DEFAULT_GENERATOR_FORMAT) {
+ RSSGeneratorConfig.DEFAULT_GENERATOR_FORMAT = DEFAULT_GENERATOR_FORMAT;
+ }
+
+ public static void setGENERATOR_DIRECTORY(String GENERATOR_DIRECTORY) {
+ RSSGeneratorConfig.GENERATOR_DIRECTORY = GENERATOR_DIRECTORY;
+ }
+
+ /**
+ *
+ * @param S la classe source de la configuration
+ */
+ public static abstract class RssGeneratorConfigInitializer<S> extends ConfigInitializer<S,RSSGeneratorConfig> {
+
+ /**
+ * Initialise RSSGeneratorConfig.
+ * @param config la configuration source
+ */
+ public void init(S config) {
+ RSSGenerator.log.info("with source "+config);
+
+ super.init(CONFIGURATION_PREFIX_PROPERTY,RSSGeneratorConfig.class, config,
+ "DEFAULT_GENERATOR_NB_ITEM",
+ "DEFAULT_GENERATOR_FORMAT",
+ "GENERATOR_DIRECTORY");
+
+ // create delegate directory
+ new java.io.File(GENERATOR_DIRECTORY).mkdirs();
+
+ }
+ }
+}
Deleted: trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorHelper.java
===================================================================
--- trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorHelper.java 2008-05-30 20:39:08 UTC (rev 75)
+++ trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorHelper.java 2008-05-31 16:33:29 UTC (rev 76)
@@ -1,298 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.codelutin.rss;
-
-import com.sun.syndication.feed.synd.SyndContent;
-import com.sun.syndication.feed.synd.SyndContentImpl;
-import com.sun.syndication.feed.synd.SyndEntry;
-import com.sun.syndication.feed.synd.SyndEntryImpl;
-import com.sun.syndication.feed.synd.SyndFeed;
-import com.sun.syndication.feed.synd.SyndFeedImpl;
-import com.sun.syndication.io.FeedException;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.EnumMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.commons.beanutils.BeanUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * helper class to write rss feeds in a file
- * @author tony
- */
-public class RSSGeneratorHelper {
-
- /** to use log facility, just put in your code: log.info(\"...\"); */
- static final Log log = LogFactory.getLog(RSSGeneratorHelper.class);
- /** date formater use to save date in feed and entries */
- static final DateFormat DATE_PARSER = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
- /** shared jvm instance */
- protected static RSSGeneratorHelper instance;
- /** dictonnary of field <-> property for feed */
- protected final EnumMap<Field, String> feedProperties;
- /** dictonnary of field <-> property for entry */
- protected final EnumMap<Field, String> itemProperties;
-
- public static RSSGeneratorHelper getInstance() {
- if (instance == null) {
- instance = new RSSGeneratorHelper();
- }
- return instance;
- }
-
- protected RSSGeneratorHelper() {
- itemProperties = new EnumMap<Field, String>(Field.class);
- feedProperties = new EnumMap<Field, String>(Field.class);
- feedProperties.put(Field.NAME, "title");
- feedProperties.put(Field.LINK, "link");
- // cela engendre des NPE...
- feedProperties.put(Field.IMAGE, "image.url");
- feedProperties.put(Field.DESCRIPTION, "description");
- feedProperties.put(Field.AUTHOR, "author");
- feedProperties.put(Field.TIME, "publishedDate");
-
- itemProperties.put(Field.NAME, "title");
- itemProperties.put(Field.LINK, "link");
- itemProperties.put(Field.IMAGE, null);
- itemProperties.put(Field.DESCRIPTION, "description.value");
- itemProperties.put(Field.AUTHOR, "author");
- itemProperties.put(Field.TIME, "publishedDate");
- }
-
- /**
- *
- * @param url location where to create the file
- * @param type fromat of feed to create
- * @param values properties of the feed
- * @throws ParseException if pb while parsing date
- * @throws IOException if io pb
- * @throws FeedException if pb while creating feed
- */
- public void createFeedFile(URL url, FeedType type, Map<Field, Object> values) throws IOException, FeedException, ParseException {
- if (url == null) {
- throw new NullPointerException("can not create a feed with null url");
- }
- if (type == null) {
- throw new NullPointerException("can not create a feed with null feedtype");
- }
- if (values == null || values.isEmpty()) {
- //TODO Should check mandatory values (title, link,...)
- throw new NullPointerException("can not create a feed with null nor empty values dictonnary");
- }
- File f = getFile(url);
-
- if (f.exists()) {
- throw new IllegalStateException("file already existing in " + url);
- }
-
- // make sure parent exists
- f.getParentFile().mkdirs();
-
- // block until can acquire lock
- FileLock lock = acquireLock(f);
-
- try {
-
- SyndFeed feed = createFeed(type, values);
-
- RSSIOUtil.saveFeed(f, feed);
-
- } finally {
- releaseLock(f, lock);
- }
- }
-
- /**
- * Add a item to an existing feed file.
- *
- * @param url location of feed to used
- * @param nbEntries number of maximum entries to be written in feed file
- * @param values dictionnary of properties to write
- * @throws FeedException if feed pb
- * @throws IOException if io pb
- * @throws ParseException if dateparser pb
- */
- public void addItemToFeedFile(URL url, int nbEntries, Map<Field, Object> values) throws IOException, FeedException, ParseException {
- if (url == null) {
- throw new NullPointerException("can not add a feed's entry with null url");
- }
- if (values == null || values.isEmpty()) {
- //TODO Should check mandatory values (title, link,...)
- throw new NullPointerException("can not add a feed's entry with null nor empty values dictonnary");
- }
- File f = getFile(url);
-
- if (!f.exists()) {
- throw new FileNotFoundException("file not existing " + f);
- }
-
- // block until can acquire lock
- FileLock lock = acquireLock(f);
-
- try {
- // get feed and add the new item
- SyndFeed feed = addItemToFeed(url, nbEntries, values);
-
- // save feed into a tmp file
- File tmpFile = new File(f.getAbsolutePath() + "-tmp_" + System.nanoTime());
-
- RSSIOUtil.saveFeed(tmpFile, feed);
-
- // move tmpFile to real file
- tmpFile.renameTo(f);
- } finally {
- releaseLock(f, lock);
- }
- }
-
- protected SyndFeed createFeed(FeedType type, Map<Field, Object> values) throws ParseException {
- SyndFeed feed = new SyndFeedImpl();
- feed.setFeedType(type.getType());
- feed.setEncoding("utf-8");
- for (Entry<Field, Object> entry : values.entrySet()) {
- Field field = entry.getKey();
- String name = feedProperties.get(field);
- if (name == null) {
- // this field is not managed
- log.warn("the field " + field + " is not managed in feed");
- continue;
- }
- Object value = entry.getValue();
- Object realValue;
- switch (field) {
- case TIME:
- realValue = DATE_PARSER.parse((String) value);
- break;
- default:
- realValue = value;
- }
-
- setFieldValue(feed, name, realValue);
- }
-
- return feed;
- }
-
- protected SyndEntry createFeedItem(Map<Field, Object> values) throws ParseException {
-
- SyndEntry feedEntry = new SyndEntryImpl();
-
- for (Entry<Field, Object> entry : values.entrySet()) {
- Field field = entry.getKey();
- String name = itemProperties.get(field);
- if (name == null) {
- // this field is not managed
- log.warn("the field " + field + " is not managed in item");
- continue;
- }
- Object value = entry.getValue();
- Object realValue;
- switch (field) {
- case TIME:
- realValue = DATE_PARSER.parse((String) value);
- break;
- case DESCRIPTION:
- //TODO Deal with xml content ?
- SyndContent description = new SyndContentImpl();
- description.setType("text/plain");
- feedEntry.setDescription(description);
- realValue = String.valueOf(value);
- break;
- default:
- realValue = value;
- }
- setFieldValue(feedEntry, name, realValue);
- }
-
- return feedEntry;
- }
-
- @SuppressWarnings({"unchecked"})
- protected SyndFeed addItemToFeed(URL url, int nbEntries, Map<Field, Object> values) throws IOException, IllegalArgumentException, FeedException, ParseException {
- SyndFeed feed = RSSIOUtil.readFeed(url);
- List<SyndEntry> entries = feed.getEntries();
- if (!entries.isEmpty()) {
- // always sort by publication date
- java.util.Collections.sort(entries, new FeedEntryComparator());
- // keep only nbEntries -1 entries
- while (entries.size() > nbEntries - 1) {
- entries.remove(0);
- }
- }
- SyndEntry item = createFeedItem(values);
- entries.add(item);
- if (log.isDebugEnabled()) {
- log.debug("new item " + item);
- }
- return feed;
- }
-
- /**
- * Obtain the file from his url location.
- *
- * @param url location of the file
- * @return the file
- * @throws java.lang.IllegalStateException if uri is not sytax valid
- */
- protected File getFile(URL url) throws IllegalStateException {
- try {
- return new File(url.toURI());
- } catch (URISyntaxException e) {
- throw new IllegalStateException("could not obtain file from url " + url, e);
- }
- }
-
- protected FileLock acquireLock(File f) throws IOException {
- File lockFile = getWriteFileLock(f);
-
- /*if (!lockFile.exists()) lockFile.createNewFile(); */
- // open file for writing only
- FileChannel channel = new RandomAccessFile(lockFile, "rw").getChannel();
-
- // block until can acquire lock
-
- return channel.lock();
- }
-
- protected File getWriteFileLock(File f) {
- return new File(f.getParentFile(), f.getName() + ".wlock");
- }
-
- protected void releaseLock(File f, FileLock lock) throws IOException {
- // release lock
- lock.release();
- // close channel
- lock.channel().close();
- // delete file lock
- File lockFile = getWriteFileLock(f);
- lockFile.delete();
- }
-
- protected void setFieldValue(Object dst, String name, Object value) {
- if (value == null) {
- // null value is not managed
- log.warn("null value for field " + name + " is not managed");
- return;
- }
- try {
- BeanUtils.setProperty(dst, name, value);
- } catch (Exception ex) {
- log.warn("could not access property " + name, ex);
- }
- }
-}
Modified: trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorServlet.java
===================================================================
--- trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorServlet.java 2008-05-30 20:39:08 UTC (rev 75)
+++ trunk/lutinrss/src/main/java/org/codelutin/rss/RSSGeneratorServlet.java 2008-05-31 16:33:29 UTC (rev 76)
@@ -1,66 +1,151 @@
package org.codelutin.rss;
+import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import java.io.*;
-import java.rmi.ServerException;
-import java.text.ParseException;
-import java.util.Date;
import java.util.HashMap;
import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import javax.servlet.*;
import javax.servlet.http.*;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
/**
* <p>
- * Servlet permettant de generer des flux generes par RSSGeneratorHelper et de
+ * Servlet permettant de generer des flux generes par RSSGenerator et de
* les publier.
*
* @author chemit
*/
-public class RSSGeneratorServlet extends HttpServlet {
+public class RSSGeneratorServlet extends BaseServlet<RSSGenerator> {
- /** to use log facility, just put in your code: log.info(\"...\"); */
- private static final Log log = LogFactory.getLog(RSSGeneratorServlet.class);
- protected transient RSSGeneratorHelper generator;
- /** directory where feeds are stored */
- protected transient File generatorDirector;
private static final long serialVersionUID = 1L;
- @Override
- public void init(ServletConfig config) throws ServletException {
- init(config, true);
+ public void doCreateFeed(HttpServletRequest request, HttpServletResponse response, String feedName, File file) throws ServletException, IOException {
+ String type = request.getParameter("feedType");
+ FeedType feedType = type != null ? FeedType.valueOf(type) : RSSGeneratorConfig.DEFAULT_GENERATOR_FORMAT;
+ String description = request.getParameter("feedDescription");
+ String link = request.getParameter("feedLink");
+ String author = request.getParameter("feedAuthor");
+ Map<Field, Object> values = new HashMap<Field, Object>();
+ values.put(Field.NAME, feedName);
+ addFieldValue(Field.DESCRIPTION, description, values);
+ addFieldValue(Field.LINK, link, values);
+ addFieldValue(Field.AUTHOR, author, values);
+ values.put(Field.TIME, RSSGenerator.DATE_PARSER.format(new java.util.Date()));
+ try {
+ delegate.createFeedFile(file.toURI().toURL(), feedType, values);
+ } catch (Exception ex) {
+ throw new ServletException(ex);
+ }
+
+ String redirect = request.getParameter("from");
+ if (redirect != null) {
+ response.sendRedirect(redirect);
+ }
}
- public void init(ServletConfig config, boolean initRssConfig) throws ServletException {
+ public void doDeleteFeed(HttpServletRequest request, HttpServletResponse response, String feedName, File file) throws ServletException, IOException {
try {
- super.init(config);
- if (initRssConfig) {
- // init depuis la config de servlet
- new RSSConfig.RSSConfigInitializer<ServletConfig>() {
+ delegate.deleteFeedFile(file.toURI().toURL());
+ } catch (Exception ex) {
+ throw new ServletException(ex);
+ }
- @Override
- protected String getConfigValue(ServletConfig config, String fullConfigName) {
- return config.getInitParameter(fullConfigName);
- }
- }.init(config);
+ String redirect = request.getParameter("from");
+ if (redirect != null) {
+ response.sendRedirect(redirect);
+ }
+ }
- // instanciate rss generaotr avec les implantation par default
- generator = RSSGeneratorHelper.getInstance();
+ public void doAddItem(HttpServletRequest request, HttpServletResponse response, String feedName, File file) throws ServletException, IOException {
+
+ Integer nbItems = convertToInt(request.getParameter("nbItems"));
+ if (nbItems == null) {
+ nbItems = RSSGeneratorConfig.DEFAULT_GENERATOR_NB_ITEM;
+ }
+ String description = request.getParameter("itemDescription");
+ String link = request.getParameter("itemLink");
+ String author = request.getParameter("itemAuthor");
+ String name = request.getParameter("itemName");
+
+ Map<Field, Object> values = new HashMap<Field, Object>();
+ addFieldValue(Field.NAME, name, values);
+ addFieldValue(Field.DESCRIPTION, description, values);
+ addFieldValue(Field.LINK, link, values);
+ addFieldValue(Field.AUTHOR, author, values);
+ values.put(Field.TIME, RSSGenerator.DATE_PARSER.format(new java.util.Date()));
+ try {
+ delegate.addItemToFeedFile(file.toURI().toURL(), nbItems, values);
+ } catch (Exception ex) {
+ throw new ServletException(ex);
+ }
+
+ String redirect = request.getParameter("from");
+ if (redirect != null) {
+ response.sendRedirect(redirect);
+ }
+ }
+
+ public void doList(HttpServletResponse response) throws IOException {
+ // obtain the list of known feeds
+ File[] files = delegate.getGeneratorDirectory().listFiles(new FileFilter() {
+
+ public boolean accept(File pathname) {
+ return pathname.isFile() && pathname.getName().endsWith(".xml");
}
- } catch (Exception eee) {
- log.warn("Can't configure Servlet", eee);
- if (eee instanceof ServletException) {
- throw (ServletException) eee;
+ });
+ response.setContentType("text/xml;charset=UTF-8");
+ PrintWriter out = response.getWriter();
+
+ try {
+ if (files.length > 0) {
+ String format = "<option value=\"%1$s\">%1$s</option>";
+ for (File f : files) {
+ String name = f.getName();
+ out.println(String.format(format, name.substring(0, name.length() - 4)));
+ }
+ } else {
+ out.println("<span class='error'>no feed generated</span>");
}
- throw new ServletException("Can't configure Servlet", eee);
+ } finally {
+ out.close();
}
}
+ public void doShow(File file, String feedName, HttpServletResponse response) throws ServletException, IOException {
+ // no action, just publication
+ if (!file.exists()) {
+ throw new ServletException("could not find feed " + feedName);
+ }
+ response.setContentType("text/xml;charset=UTF-8");
+ PrintWriter out = response.getWriter();
+ try {
+ SyndFeed feed = RSSIOUtil.readFeed(file.toURI().toURL());
+ RSSIOUtil.saveFeed(out, feed);
+ } catch (IllegalArgumentException ex) {
+ throw new ServletException(ex);
+ } catch (FeedException ex) {
+ throw new ServletException(ex);
+ } finally {
+ out.close();
+ }
+ }
+
+ @Override
+ protected ConfigInitializer<ServletConfig,?> newConfigInitializer() {
+ return new RSSGeneratorConfig.RssGeneratorConfigInitializer<ServletConfig>() {
+
+ protected String getConfigValue(ServletConfig config, String fullConfigName) {
+ return config.getInitParameter(fullConfigName);
+ }
+ };
+ }
+
+ @Override
+ protected RSSGenerator newDelegate() throws Exception {
+ return RSSGenerator.newDefaultInstance();
+ }
+
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
@@ -68,141 +153,55 @@
* @throws java.io.IOException TODO
* @throws ServletException TODO
*/
- public void processRequest(HttpServletRequest request, HttpServletResponse response)
+ @Override
+ protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
- if (action==null) action="";
+ if (action == null) {
+ action = "";
+ }
action = action.trim().toLowerCase();
if ("list".equals(action)) {
- // obtain the list of known feeds
- File[] files = getGeneratorDirector().listFiles(new FilenameFilter() {
-
- public boolean accept(File dir, String name) {
- return name.endsWith(".xml");
- }
- });
- response.setContentType("text/xml;charset=UTF-8");
- PrintWriter out = response.getWriter();
-
- try {
- if (files.length > 0) {
- String format = "<option value=\"%1$s\">%1$s</option>";
- for (File f : files) {
- String name = f.getName();
- out.println(String.format(format, name.substring(0, name.length() - 4)));
- }
- } else {
- out.println("no feed generated");
- }
- } finally {
- out.close();
- }
+ doList(response);
return;
}
+
String feedName = request.getParameter("feedName");
+
if (feedName == null || "".equals(feedName)) {
- throw new ServerException("could not find feedName parameter");
+ throw new ServletException("could not find feedName parameter");
}
+ //feedName =new String(feedName.getBytes(),0,feedName.length(),Charset.forName("utf-8"));
+ File file = new File(delegate.getGeneratorDirectory(), feedName + ".xml");
- File file = new File(getGeneratorDirector(), feedName + ".xml");
-
- if ("".equals(action)) {
- // no action, just publication
- if (!file.exists()) {
- throw new ServletException("could not find feed to publish " + feedName);
- }
- response.setContentType("text/xml;charset=UTF-8");
- PrintWriter out = response.getWriter();
- try {
- StringBuffer sb = new StringBuffer();
-
- FileReader reader = new FileReader(file);
- BufferedReader breader = new BufferedReader(reader);
- String line = null;
- while ((line = breader.readLine()) != null) {
- sb.append(line).append('\n');
- }
- out.println(sb.toString());
- return;
- } finally {
- out.close();
- }
+ if ("show".equals(action)) {
+ doShow(file, feedName, response);
+ return;
}
-
+
if ("create".equals(action)) {
- String type = request.getParameter("feedType");
- FeedType feedType = type != null ? FeedType.valueOf(type) : RSSConfig.DEFAULT_GENERATOR_FORMAT;
- String description = request.getParameter("feedDescription");
- String link = request.getParameter("feedLink");
+ doCreateFeed(request, response, feedName, file);
+ return;
+ }
- Map<Field, Object> values = new HashMap<Field, Object>();
- values.put(Field.NAME, feedName);
- values.put(Field.DESCRIPTION, description);
- values.put(Field.LINK, link);
- values.put(Field.TIME, RSSGeneratorHelper.DATE_PARSER.format(new java.util.Date()));
- try {
-
- generator.createFeedFile(file.toURI().toURL(), feedType, values);
- } catch (Exception ex) {
- throw new ServletException(ex);
- }
-
- String redirect = request.getParameter("from");
- if (redirect != null) {
- response.sendRedirect(redirect);
- }
+ if ("delete".equals(action)) {
+ doDeleteFeed(request, response, feedName, file);
return;
}
if ("additem".equals(action)) {
-
- String redirect = request.getParameter("from");
- if (redirect != null) {
- response.sendRedirect(redirect);
- }
+ doAddItem(request, response, feedName, file);
return;
}
- throw new ServletException("action " + action + "is unknown ");
+ throw new ServletException("action '" + action + "' is unknown ");
}
- public File getGeneratorDirector() {
- if (generatorDirector == null) {
- generatorDirector = new File(RSSConfig.GENERATOR_DIRECTORY);
+ protected void addFieldValue(Field field, String value, Map<Field, Object> values) {
+ if (value != null && !"".equals(value.trim())) {
+ values.put(field, value);
}
- return generatorDirector;
}
- // <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
- */
- @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
- */
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- processRequest(request, response);
- }
-
- /**
- * Returns a short description of the servlet.
- */
- @Override
- public String getServletInfo() {
- return "RSS Publication Servlet";
- }
- // </editor-fold>
}
Modified: trunk/lutinrss/src/main/java/org/codelutin/rss/RSSHelper.java
===================================================================
--- trunk/lutinrss/src/main/java/org/codelutin/rss/RSSHelper.java 2008-05-30 20:39:08 UTC (rev 75)
+++ trunk/lutinrss/src/main/java/org/codelutin/rss/RSSHelper.java 2008-05-31 16:33:29 UTC (rev 76)
@@ -20,7 +20,7 @@
public class RSSHelper {
/** to use log facility, just put in your code: log.info(\"...\"); */
- private static final Log log = LogFactory.getLog(RSSHelper.class);
+ static final Log log = LogFactory.getLog(RSSHelper.class);
/**
*
Modified: trunk/lutinrss/src/main/java/org/codelutin/rss/RSSIOUtil.java
===================================================================
--- trunk/lutinrss/src/main/java/org/codelutin/rss/RSSIOUtil.java 2008-05-30 20:39:08 UTC (rev 75)
+++ trunk/lutinrss/src/main/java/org/codelutin/rss/RSSIOUtil.java 2008-05-31 16:33:29 UTC (rev 76)
@@ -1,16 +1,27 @@
package org.codelutin.rss;
+import com.sun.syndication.feed.synd.SyndContent;
+import com.sun.syndication.feed.synd.SyndContentImpl;
+import com.sun.syndication.feed.synd.SyndEntry;
+import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.feed.synd.SyndFeedImpl;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.SyndFeedOutput;
import com.sun.syndication.io.XmlReader;
-import java.io.BufferedWriter;
import java.io.File;
-import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.net.URL;
+import java.text.ParseException;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
* helper to read or save a feed
@@ -18,6 +29,9 @@
*/
public class RSSIOUtil {
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static final Log log = LogFactory.getLog(RSSIOUtil.class);
+
/**
* Load a feed from his url
* @param url location of feed
@@ -34,24 +48,121 @@
/**
* save a feed into a file.
- * @param f
+ * @param file
* @param feed
* @throws java.io.IOException
* @throws com.sun.syndication.io.FeedException
*/
- public static void saveFeed(File f, SyndFeed feed) throws IOException, FeedException {
+ public static void saveFeed(File file, SyndFeed feed) throws IOException, FeedException {
+ SyndFeedOutput output = new SyndFeedOutput();
+ output.output(feed, file);
+ }
+
+ /**
+ * save a feed into a writer.
+ * @param writer
+ * @param feed
+ * @throws java.io.IOException
+ * @throws com.sun.syndication.io.FeedException
+ */
+ public static void saveFeed(Writer writer, SyndFeed feed) throws IOException, FeedException {
+ SyndFeedOutput output = new SyndFeedOutput();
+ output.output(feed, writer);
+ }
- Writer writer = new BufferedWriter(new FileWriter(f));
- try {
- SyndFeedOutput output = new SyndFeedOutput();
- output.output(feed, writer);
- } finally {
- if (writer != null) {
- writer.close();
+ public static SyndFeed createFeed(EnumMap<Field, String> feedProperties, FeedType type, Map<Field, Object> values) throws ParseException {
+ SyndFeed feed = new SyndFeedImpl();
+ feed.setFeedType(type.getType());
+ feed.setEncoding("utf-8");
+ for (Entry<Field, Object> entry : values.entrySet()) {
+ Field field = entry.getKey();
+ String name = feedProperties.get(field);
+ if (name == null) {
+ // this field is not managed
+ log.warn("the field " + field + " is not managed in feed");
+ continue;
}
+ Object value = entry.getValue();
+ Object realValue;
+ switch (field) {
+ case TIME:
+ realValue = RSSGenerator.DATE_PARSER.parse((String) value);
+ break;
+ default:
+ realValue = value;
+ }
+
+ setFieldValue(feed, name, realValue);
}
+
+ return feed;
}
+ @SuppressWarnings({"unchecked"})
+ protected static SyndFeed addItemToFeed(SyndFeed feed, SyndEntry item, int nbEntries, Map<Field, Object> values) throws IOException, IllegalArgumentException, FeedException, ParseException {
+ List<SyndEntry> entries = feed.getEntries();
+ if (!entries.isEmpty()) {
+ // always sort by publication date
+ java.util.Collections.sort(entries, new FeedEntryComparator());
+ // keep only nbEntries -1 entries
+ while (entries.size() > nbEntries - 1) {
+ entries.remove(0);
+ }
+ }
+ entries.add(item);
+ if (log.isDebugEnabled()) {
+ log.debug("new item " + item);
+ }
+ return feed;
+ }
+
+ public static SyndEntry createFeedItem(EnumMap<Field, String> itemProperties, Map<Field, Object> values) throws ParseException {
+
+ SyndEntry feedEntry = new SyndEntryImpl();
+
+ for (Entry<Field, Object> entry : values.entrySet()) {
+ Field field = entry.getKey();
+ String name = itemProperties.get(field);
+ if (name == null) {
+ // this field is not managed
+ log.warn("the field " + field + " is not managed in item");
+ continue;
+ }
+ Object value = entry.getValue();
+ Object realValue;
+ switch (field) {
+ case TIME:
+ realValue = RSSGenerator.DATE_PARSER.parse((String) value);
+ break;
+ case DESCRIPTION:
+ //TODO Deal with xml content ?
+ SyndContent description = new SyndContentImpl();
+ description.setType("text/plain");
+ feedEntry.setDescription(description);
+ realValue = String.valueOf(value);
+ break;
+ default:
+ realValue = value;
+ }
+ setFieldValue(feedEntry, name, realValue);
+ }
+
+ return feedEntry;
+ }
+
+ protected static void setFieldValue(Object dst, String name, Object value) {
+ if (value == null) {
+ // null value is not managed
+ log.warn("null value for field " + name + " is not managed");
+ return;
+ }
+ try {
+ BeanUtils.setProperty(dst, name, value);
+ } catch (Exception ex) {
+ log.warn("could not access property " + name, ex);
+ }
+ }
+
protected RSSIOUtil() {
// no instance
}
Modified: trunk/lutinrss/src/main/java/org/codelutin/rss/RSSServlet.java
===================================================================
--- trunk/lutinrss/src/main/java/org/codelutin/rss/RSSServlet.java 2008-05-30 20:39:08 UTC (rev 75)
+++ trunk/lutinrss/src/main/java/org/codelutin/rss/RSSServlet.java 2008-05-31 16:33:29 UTC (rev 76)
@@ -4,8 +4,6 @@
import javax.servlet.*;
import javax.servlet.http.*;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
/**
* <p>
@@ -30,15 +28,9 @@
* </p>
* @author poussin
*/
-public class RSSServlet extends HttpServlet {
+public class RSSServlet extends BaseServlet<RSSHelper> {
- /** to use log facility, just put in your code: log.info(\"...\"); */
- private static final Log log = LogFactory.getLog(RSSServlet.class);
/**
- * L'objet permettant de recupérer la representation HTML d'un feed
- */
- protected transient RSSHelper rss;
- /**
* Le code JavaScript a utilise dans les pages clientes
*
* Provient du fichier rssinclude.js
@@ -84,12 +76,12 @@
" var toTreate = [];\n" +
" while (i < max) {\n" +
" var div = divs[i++];\n" +
- " if (div.getAttribute('name')=='rssinclude') toTreate[toTreate.length] = div;\n"+
+ " if (div.getAttribute('name')=='rssinclude') toTreate[toTreate.length] = div;\n" +
" }\n" +
" i=0;max = toTreate.length;\n" +
- " while (i<max) rssincludeUpdateDiv(toTreate[i++], true);"+
- "}\n"+
- "if (window.addEventListener) window.addEventListener( 'load', initRss,false);\n"+
+ " while (i<max) rssincludeUpdateDiv(toTreate[i++], true);" +
+ "}\n" +
+ "if (window.addEventListener) window.addEventListener( 'load', initRss,false);\n" +
"else if (window.attachEvent) window.attachEvent( 'onload', initRss);";
private static final long serialVersionUID = 1L;
@@ -103,36 +95,46 @@
return code;
}
- @Override
- public void init(ServletConfig config) throws ServletException {
- init(config, true);
+ public void doJs(HttpServletResponse response, HttpServletRequest request) throws IOException {
+ // on renvoie le code js
+ response.setContentType("text/plain;charset=UTF-8");
+ PrintWriter out = response.getWriter();
+ try {
+ String code = getJs(request.getRequestURL().toString());
+ out.println(code);
+ } finally {
+ out.close();
+ }
}
- public void init(ServletConfig config, boolean initRssConfig) throws ServletException {
+ public void doRender(HttpServletResponse response, HttpServletRequest request, String feedName) throws IOException {
+ response.setContentType("text/html;charset=UTF-8");
+ PrintWriter out = response.getWriter();
try {
- super.init(config);
- if (initRssConfig) {
- // init depuis la config de servlet
- new RSSConfig.RSSConfigInitializer<ServletConfig>() {
+ String feedRepr = request.getParameter("feedRepr");
+ Integer nbItem = convertToInt(request.getParameter("nbItem"));
+ boolean forceReload = "true".equalsIgnoreCase(request.getParameter("forceReload"));
+ out.println(delegate.getHTML(feedName, feedRepr, nbItem, forceReload));
+ } finally {
+ out.close();
+ }
+ }
- @Override
- protected String getConfigValue(ServletConfig config, String fullConfigName) {
- return config.getInitParameter(fullConfigName);
- }
- }.init(config);
+ @Override
+ protected ConfigInitializer<ServletConfig,? > newConfigInitializer() {
+ return new RSSConfig.RSSConfigInitializer<ServletConfig>() {
- // instanciate rss avec les implanatation par defaut
- rss = RSSHelper.newDefaultInstance();
+ protected String getConfigValue(ServletConfig config, String fullConfigName) {
+ return config.getInitParameter(fullConfigName);
}
- } catch (Exception eee) {
- log.warn("Can't configure Servlet", eee);
- if (eee instanceof ServletException) {
- throw (ServletException) eee;
- }
- throw new ServletException("Can't configure Servlet", eee);
- }
+ };
}
+ @Override
+ protected RSSHelper newDelegate() throws Exception {
+ return RSSHelper.newDefaultInstance();
+ }
+
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
@@ -140,72 +142,14 @@
* @throws java.io.IOException TODO
* @throws ServletException TODO
*/
- public void processRequest(HttpServletRequest request, HttpServletResponse response)
+ @Override
+ protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String feedName = request.getParameter("feedName");
if (feedName == null || "".equals(feedName)) {
- // on renvoie le code js
- response.setContentType("text/plain;charset=UTF-8");
- PrintWriter out = response.getWriter();
- try {
- String code = getJs(request.getRequestURL().toString());
- out.println(code);
- } finally {
- out.close();
- }
+ doJs(response, request);
} else {
- response.setContentType("text/html;charset=UTF-8");
- PrintWriter out = response.getWriter();
- try {
- String feedRepr = request.getParameter("feedRepr");
- Integer nbItem = convertToInt(request.getParameter("nbItem"));
- boolean forceReload = "true".equalsIgnoreCase(request.getParameter("forceReload"));
- out.println(rss.getHTML(feedName, feedRepr, nbItem, forceReload));
- } finally {
- out.close();
- }
+ doRender(response, request, feedName);
}
}
-
- protected Integer convertToInt(String parameter) {
- Integer result = null;
- try {
- result = Integer.parseInt(parameter);
- } catch (Exception eee) {
- log.debug("Can't convert to int: '" + parameter + "'", eee);
- }
- return result;
- }
- // <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
- */
- @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
- */
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- processRequest(request, response);
- }
-
- /**
- * Returns a short description of the servlet.
- */
- @Override
- public String getServletInfo() {
- return "RSS Servlet";
- }
- // </editor-fold>
}