package com.mckessonaps.jspwiki.plugin.emailnotifier; import java.util.Arrays; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.log4j.Category; import com.ecyrd.jspwiki.WikiPage; /** * Represents an individual person who is interested in being notified of changes. */ class Subscriber { private static final Category log = Category.getInstance( Subscriber.class ); /** * Attempt to parse the canidateLine into a Subscription. If line does not look * like subscription information null is returned. * @param canidateLine * @return May be null if canidateLine did not represent * a subscription. */ static Subscriber parse(String canidateLine) { //Simple short crcuit if the line doesn't start with a * then we can definitly ignore it. if (! canidateLine.startsWith( "*") ) return null; String piecesArray[] = canidateLine.split("\\s"); // minimumally canidate line must have: "* name domain houroffset"... if (piecesArray.length < 4) return null; if (!piecesArray[0].equals( "*")) return null; String email = piecesArray[1] + "@" + piecesArray[2]; int hourOffset = hourOffsetFrom(piecesArray[3]); //Remove the known elements from the front, the remaineder is the page list... List pageList = Arrays.asList( piecesArray ); pageList = pageList.subList( 4, pageList.size()); // 0, 1, 2, 3 Junk these list elements... //"*", "name", "domain", "houroffset" return new Subscriber(email, hourOffset, pageList); } /** * Return an hour offset from midnight, will extract 0 to 23 from given string * s, if string is unparsable returns an offset of 0. */ private static int hourOffsetFrom(String s) { int offset = 0; try { offset = Integer.parseInt( s ); //anything offset = (offset % 23); // -23 to 23 offset = (offset + 23); // 0 to 46 offset = (offset % 23); // 0 to 23 } catch (NumberFormatException nfe) { log.warn("Unparsable hour offset encountered.", nfe); } return offset; } /** email address of the subscriber. */ private final String m_emailAddress; /** hour offset from server midnight at which the user wants to be notified. */ private final int m_hourOffset; /** list of pages (possibly decorated) that the subscriber is interested in. */ private final List m_pageList; /** * Constructor, doesn't do much but assign some member fields. Private as the * static parse method should be used to create subscriber instances. */ private Subscriber(String emailAddress, int hourOffset, List pageList) { m_emailAddress = emailAddress; m_hourOffset = hourOffset; m_pageList = pageList; } /** * A subscriber specifies an hour offset from server midnight at which they want thier * notifications sent, given the Date d should this subscriber have his * notification sent now? */ boolean shouldSendAt(Date d) { return (d.getHours() == m_hourOffset) ; } /** * Returns string containing a list of the changedPages that this subscriber is interested in receiving. * For each subscribed page in changedPages the page's name is substituted for pageToken in pagePattern */ String getListOfChangedSubscribedPages(Map changedPageMap, String pagePattern) { StringBuffer sb = new StringBuffer(); for (Iterator iter = changedPageMap.keySet().iterator(); iter.hasNext();) { String pageName = (String)iter.next(); //If the subscribers page list is empty he wants all changes, otherwise he only wnat pages that he listed... if ((!m_pageList.isEmpty()) && (!m_pageList.contains( pageName )) ) continue; String bodyElement = pagePattern.replaceAll(NotifierTask.MARKER_CHANGED_PAGE_NAME, pageName); List versionList = (List)changedPageMap.get(pageName); bodyElement = bodyElement.replaceAll(NotifierTask.MARKER_CHANGED_PAGE_INFO, buildChangeInfo(versionList)); sb.append( bodyElement ); } return sb.toString(); } private String buildChangeInfo(List pageVersions) { StringBuffer buffer = new StringBuffer(); String previousAuthor = null; for (Iterator iter = pageVersions.iterator(); iter.hasNext();) { WikiPage page = (WikiPage) iter.next(); String author = page.getAuthor(); //FIX: for NPE if (author !=null) { if (! author.equals( previousAuthor )) { if (buffer.length() > 0) buffer.append( ", "); buffer.append( author ); } previousAuthor = author; } } return buffer.toString(); } /** * Simple getter so outsiders can get what address to send to. */ public String getEmailAddress() { return m_emailAddress; } }