// BlogBridge -- RSS feed reader, manager, and web based service // Copyright (C) 2002-2007 by R. Pito Salas // // This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software Foundation; // either version 2 of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along with this program; // if not, write to the Free Software Foundation, Inc., 59 Temple Place, // Suite 330, Boston, MA 02111-1307 USA // // Contact: R. Pito Salas // mailto:pitosalas@users.sourceforge.net // More information: about BlogBridge // http://www.blogbridge.com // http://sourceforge.net/projects/blogbridge // // $Id: ArticleAutoSaver.java,v 1.3 2007/05/02 10:27:06 spyromus Exp $ // package com.salas.bb.core.autosave; import com.jgoodies.uif.util.ResourceUtils; import com.salas.bb.domain.DirectFeed; import com.salas.bb.domain.IArticle; import com.salas.bb.domain.IFeed; import com.salas.bb.domain.NetworkFeed; import com.salas.bb.utils.StringUtils; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.net.URL; import java.text.MessageFormat; import java.util.Date; import java.util.concurrent.Executor; import java.util.logging.Level; import java.util.logging.Logger; /** * When a new article comes, this saver checks if the * saving is enabled for the parent feed and saves an article * if it is. */ class ArticleAutoSaver extends AbstractAutoSaver { private static final Logger LOG = Logger.getLogger(AbstractAutoSaver.class.getName()); private MessageFormat textTemplate; /** * Invoked when a new article is added. * * @param article new article. * @param feed feed it was added (not necessarily parent, if it's search feed for ex.) */ protected void onNewArticle(IArticle article, IFeed feed) { boolean asa = feed.isAutoSaveArticles(); String asaFolder = feed.getAutoSaveArticlesFolder(); // If asa is disabled or article folder is not set, do nothing if (!asa || StringUtils.isEmpty(asaFolder)) return; Executor ex = getExecutor(); ex.execute(new SaveArticleTask(article, feed, asaFolder)); } /** * Returns the name of the executor thread. * * @return thread. */ protected String getExecutorThreadName() { return "Article Auto Saver"; } /** * Article saving task. */ private class SaveArticleTask implements Runnable { private final IArticle article; private final IFeed feed; private final String folder; /** * Creates a task for a give article / feed to save it to the folder. * * @param article article. * @param feed feed. * @param folder folder. */ public SaveArticleTask(IArticle article, IFeed feed, String folder) { this.article = article; this.feed = feed; this.folder = folder; } /** * Invoked when saving begins. */ public void run() { // Prepare file name String asaNameFormat = feed.getAutoSaveArticlesNameFormat(); File file = prepareFilename(folder, asaNameFormat, feed, article.getTitle(), ".html"); if (file.exists()) return; ensureAllDirsPresent(file); // Prepare the text String text = getText(article, getOffset(asaNameFormat)); // Write try { writeString(file, text); } catch (IOException e) { LOG.log(Level.WARNING, "Failed to auto-save article", e); } } } /** * Returns the offset from the root folder to the given. * * @param format format. * * @return offset. */ private static String getOffset(String format) { int i = StringUtils.countMatches(format, "/"); i += StringUtils.countMatches(format, "\\"); return StringUtils.repeat("../", i); } /** * Returns the formatted text of an article. * * @param article article. * @param folder the folder where * * @return text. */ private String getText(IArticle article, String folder) { String articleTitle = article.getTitle(); String articleText = article.getHtmlText(); String articleAuthor = article.getAuthor(); String articleLink = toString(article.getLink()); IFeed feed = article.getFeed(); String feedTitle, feedAuthor, feedLink; feedTitle = feed == null ? "Unknown" : feed.getTitle(); feedAuthor = (feed instanceof DirectFeed) ? ((DirectFeed)feed).getAuthor() : ""; feedLink = (feed instanceof NetworkFeed) ? toString(((NetworkFeed)feed).getXmlURL()) : ""; String stylesheetTag = "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + folder + "style.css\" />"; return getTextTemplate().format(new Object[] { articleTitle, articleText, articleAuthor, articleLink, feedTitle, feedAuthor, feedLink, stylesheetTag, new Date() }); } private synchronized MessageFormat getTextTemplate() { if (textTemplate == null) { String tt = ResourceUtils.readTextFromFile(ResourceUtils.getString("auto.saver.article.template")); tt = replace(tt, "article.title", "article.text", "article.author", "article.link", "feed.title", "feed.author", "feed.link", "stylesheet.tag"); tt = replaceDate(tt, "current.date", 8); textTemplate = new MessageFormat(tt); } return textTemplate; } /** * Writes the text to the file. * * @param file file. * @param text text to write. * * @throws IOException in case of an error. */ private void writeString(File file, String text) throws IOException { FileWriter fw = new FileWriter(file); fw.write(text); fw.flush(); fw.close(); } /** * Converts the link to string. * * @param link link. * * @return string. */ private String toString(URL link) { return link == null ? null : link.toString(); } }