package de.ldj.jspwiki.plugin; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Random; import org.apache.log4j.Logger; import com.ecyrd.jspwiki.WikiContext; import com.ecyrd.jspwiki.WikiEngine; import com.ecyrd.jspwiki.WikiPage; import com.ecyrd.jspwiki.plugin.WikiPlugin; import com.ecyrd.jspwiki.providers.ProviderException; /** * The FortuneCookie will return a random line from a cookies page on each call. * * @author Maik Scheibler */ public class FortuneCookie implements WikiPlugin { private static final String LINE_COMMENT = "//"; private static final String BULLET_ITEM = "*"; private static final String NUMBER_ITEM = "#"; private static final String LINEBREAK = "\\\\"; private static final Logger LOG = Logger.getLogger(FortuneCookie.class); private static final Random RANDOM = new Random(System.currentTimeMillis()); private static List m_fortuneCookies = new ArrayList(); private static Date m_pageLastModified; /** * {@inheritDoc} */ public String execute(WikiContext context, Map params) { String cookiesPageName = (String) params.get("page"); if (cookiesPageName == null || cookiesPageName.trim().isEmpty()) return getErrorSpan("You need to specify a cookies page."); WikiEngine wikiEngine = context.getEngine(); try { if (!wikiEngine.pageExists(cookiesPageName)) return getErrorSpan("The cookies page '" + cookiesPageName + "' could not be found."); WikiPage cookiesPage = wikiEngine.getPage(wikiEngine .getFinalPageName(cookiesPageName)); synchronized (FortuneCookie.class) { if (m_pageLastModified == null || m_pageLastModified.before(cookiesPage .getLastModified())) updateCookies(wikiEngine, cookiesPage); } } catch (ProviderException ex) { String message = "failed to aquire cookies final page name"; LOG.error(message, ex); return getErrorSpan(message); } catch (IOException ex) { String message = "failed to read cookies page content"; LOG.error(message, ex); return getErrorSpan(message); } if (m_fortuneCookies.isEmpty()) return getErrorSpan("The cookies page does not contain any non empty lines."); String line = m_fortuneCookies.get(RANDOM.nextInt(m_fortuneCookies .size())); // translate the selected cookie from Wiki markup to HTML String htmlCookie = wikiEngine.textToHTML(context, line); return htmlCookie; } /** * Updates the available cookies from the cookies page. * * @param wikiEngine * of this wiki * @param cookiesPage * which contains the cookies * @throws IOException * in case the page content could not be read */ private void updateCookies(WikiEngine wikiEngine, WikiPage cookiesPage) throws IOException { m_fortuneCookies.clear(); String pureCookiesText = wikiEngine.getPureText(cookiesPage); BufferedReader reader = new BufferedReader(new StringReader( pureCookiesText)); String line = null; while ((line = reader.readLine()) != null) { line = line.trim(); if (line.isEmpty() || line.startsWith(LINE_COMMENT)) continue; // strip bullet, numeration or line breaks from the content if (line.startsWith(BULLET_ITEM) || line.startsWith(NUMBER_ITEM)) line = line.substring(BULLET_ITEM.length()); if (line.endsWith(LINEBREAK)) line = line.substring(0, line.length() - LINEBREAK.length()); m_fortuneCookies.add(line.trim()); } m_pageLastModified = cookiesPage.getLastModified(); } /** * Creates an error message span. * * @param errorMsg * to display * @return the error as HTML */ private String getErrorSpan(String errorMsg) { return "" + FortuneCookie.class.getName() + ":
" + errorMsg + "
"; } }