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;
}
}