RefererLogPlugin.java [plain text]
package org.blojsom.plugin.referer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.blojsom.BlojsomException;
import org.blojsom.blog.BlogEntry;
import org.blojsom.blog.BlogUser;
import org.blojsom.blog.BlojsomConfiguration;
import org.blojsom.plugin.BlojsomPlugin;
import org.blojsom.plugin.BlojsomPluginException;
import org.blojsom.util.BlojsomConstants;
import org.blojsom.util.BlojsomProperties;
import org.blojsom.util.BlojsomUtils;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
public class RefererLogPlugin implements BlojsomPlugin {
private static final String HEADER_REFERER = "referer";
private static final String REFERER_CONFIG_IP = "plugin-referer";
private static final String REFERER_LOG_HEADER = "blojsom referer log";
private static final int FIELD_FLAVOR = 0;
private static final int FIELD_DATE = 1;
private static final int FIELD_COUNT = 2;
private static final String HITCOUNTER_KEY = ".hitcounter";
private static final String COMMENTED_LINE = "#";
private static final int REFERER_MAX_LENGTH_DEFAULT = 40;
private static final String REFERER_LOG_FILE_IP = "referer-filename";
private static final String REFERER_MAX_LENGTH_IP = "referer-display-size";
private static final String REFERER_HIT_COUNTS_IP = "hit-count-flavors";
public static final String REFERER_DATE_FORMAT = "yyyy-MM-dd";
public static final String REFERER_CONTEXT_NAME = "REFERER_HISTORY";
public static final String REFERER_CONTEXT_MAX_LENGTH = "REFERER_MAX_LENGTH";
private Log _logger = LogFactory.getLog(RefererLogPlugin.class);
private Map _refererUsers;
private List populateBlacklistPatterns(ServletConfig servletConfig, String blacklistFile) {
ArrayList blacklistPatterns = new ArrayList(5);
InputStream is = servletConfig.getServletContext().getResourceAsStream(blacklistFile);
if (is != null) {
try {
_logger.info("Processing blacklist filter [" + blacklistFile + "]");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String regexp = null;
while (((regexp = br.readLine()) != null)) {
if (!regexp.startsWith(COMMENTED_LINE) && !"".equals(regexp)) {
blacklistPatterns.add(Pattern.compile(regexp));
}
}
br.close();
} catch (IOException e) {
_logger.error(e);
}
}
return blacklistPatterns;
}
private boolean isBlacklisted(List blacklistPatterns, String referer) {
boolean result = false;
if (blacklistPatterns != null) {
int count = blacklistPatterns.size();
if (referer != null && count > 0) {
for (int x = 0; x < count; x++) {
result = ((Pattern) blacklistPatterns.get(x)).matcher(referer).find();
if (result) {
break;
}
}
}
}
return result;
}
private void loadRefererLog(String refererlog, List blacklistPatterns, Map refererGroups, List hitCountFlavors) {
File _refererfile = new File(refererlog);
if (_refererfile.exists()) {
Properties _refererproperties = new BlojsomProperties();
try {
InputStream is = new FileInputStream(_refererfile);
_refererproperties.load(is);
is.close();
Enumeration _refererenum = _refererproperties.keys();
while (_refererenum.hasMoreElements()) {
String _key = (String) _refererenum.nextElement();
String[] _details = BlojsomUtils.parseDelimitedList(_key, ".");
String _flavor = _details[FIELD_FLAVOR];
String _url = (String) _refererproperties.get(_key);
if (!isBlacklisted(blacklistPatterns, _url)) {
BlogRefererGroup _group;
if (refererGroups.containsKey(_flavor)) {
_group = (BlogRefererGroup) refererGroups.get(_flavor);
} else {
_group = new BlogRefererGroup(hitCountFlavors.contains(_flavor));
}
if (hitCountFlavors.contains(_flavor)) {
_group.addHitCount(getDateFromReferer(_details[FIELD_DATE]), Integer.parseInt(_details[FIELD_COUNT]));
} else {
_group.addReferer(_flavor, _url, getDateFromReferer(_details[FIELD_DATE]), Integer.parseInt(_details[FIELD_COUNT]));
}
refererGroups.put(_flavor, _group);
}
}
} catch (IOException e) {
_logger.error(e);
}
}
}
public void init(ServletConfig servletConfig, BlojsomConfiguration blojsomConfiguration) throws BlojsomPluginException {
String refererConfiguration = servletConfig.getInitParameter(REFERER_CONFIG_IP);
if (BlojsomUtils.checkNullOrBlank(refererConfiguration)) {
throw new BlojsomPluginException("No value given for: " + REFERER_CONFIG_IP + " configuration parameter");
}
String[] users = blojsomConfiguration.getBlojsomUsers();
_refererUsers = new HashMap(users.length);
for (int i = 0; i < users.length; i++) {
String user = users[i];
Properties refererProperties = new BlojsomProperties();
String configurationFile = blojsomConfiguration.getBaseConfigurationDirectory() + user + '/' + refererConfiguration;
InputStream is = servletConfig.getServletContext().getResourceAsStream(configurationFile);
if (is == null) {
_logger.info("No referer log configuration file found: " + configurationFile);
} else {
try {
refererProperties.load(is);
is.close();
int refererMaxLength = REFERER_MAX_LENGTH_DEFAULT;
List hitCountFlavors = new ArrayList();
String refererLog;
try {
BlogUser blog = blojsomConfiguration.loadBlog(user);
String blogUrlFilter = blog.getBlog().getBlogURL();
String maxlength = refererProperties.getProperty(REFERER_MAX_LENGTH_IP);
if (maxlength != null) {
try {
refererMaxLength = Integer.parseInt(maxlength);
} catch (NumberFormatException e) {
refererMaxLength = REFERER_MAX_LENGTH_DEFAULT;
}
}
String hitcounters = refererProperties.getProperty(REFERER_HIT_COUNTS_IP);
if (hitcounters != null) {
String[] _hitflavors = BlojsomUtils.parseCommaList(hitcounters);
for (int x = 0; x < _hitflavors.length; x++) {
hitCountFlavors.add(_hitflavors[x]);
}
_logger.info("Hit count flavors = " + hitCountFlavors.size());
}
refererLog = refererProperties.getProperty(REFERER_LOG_FILE_IP);
String blacklistFilename = refererProperties.getProperty(BlojsomConstants.BLOG_BLACKLIST_FILE_IP);
List blacklist = new ArrayList();
if (BlojsomUtils.checkNullOrBlank(blacklistFilename)) {
_logger.error("No value given for: " + BlojsomConstants.BLOG_BLACKLIST_FILE_IP + " configuration parameter for user: " + user);
} else {
blacklistFilename = blojsomConfiguration.getBaseConfigurationDirectory() + user + '/' + blacklistFilename;
blacklist = populateBlacklistPatterns(servletConfig, blacklistFilename);
}
Map refererGroups = new HashMap(5);
loadRefererLog(refererLog, blacklist, refererGroups, hitCountFlavors);
RefererLogConfiguration refererLogConfiguration = new RefererLogConfiguration(blacklist, refererLog, blogUrlFilter, refererGroups, hitCountFlavors, refererMaxLength);
_refererUsers.put(user, refererLogConfiguration);
} catch (BlojsomException e) {
_logger.error(e);
}
} catch (IOException e) {
_logger.error(e);
throw new BlojsomPluginException(e);
}
}
}
}
public BlogEntry[] process(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
BlogUser user,
Map context,
BlogEntry[] entries) throws BlojsomPluginException {
String referer = httpServletRequest.getHeader(HEADER_REFERER);
String flavor = httpServletRequest.getParameter(BlojsomConstants.FLAVOR_PARAM);
String userId = user.getId();
RefererLogConfiguration refererLogConfiguration = (RefererLogConfiguration) _refererUsers.get(userId);
if (refererLogConfiguration == null) {
return entries;
} else {
List hitCountFlavors = refererLogConfiguration.getHitCountFlavors();
Map refererGroups = refererLogConfiguration.getRefererGroups();
if (!isBlacklisted(refererLogConfiguration.getBlacklistPatterns(), referer)) {
if (flavor == null) {
flavor = BlojsomConstants.DEFAULT_FLAVOR_HTML;
}
if (hitCountFlavors.contains(flavor)) {
_logger.debug("[HitCounter] flavor=" + flavor + " - referer=" + referer);
BlogRefererGroup group;
if (refererGroups.containsKey(flavor)) {
group = (BlogRefererGroup) refererGroups.get(flavor);
} else {
group = new BlogRefererGroup(true);
}
group.addHitCount(new Date(), 1);
refererGroups.put(flavor, group);
} else if ((referer != null) && (!referer.startsWith(refererLogConfiguration.getBlogUrlFilter()))) {
_logger.debug("[Referer] flavor=" + flavor + " - referer=" + referer);
BlogRefererGroup group;
if (refererGroups.containsKey(flavor)) {
group = (BlogRefererGroup) refererGroups.get(flavor);
} else {
group = new BlogRefererGroup(hitCountFlavors.contains(flavor));
}
group.addReferer(flavor, referer, new Date());
refererGroups.put(flavor, group);
}
}
context.put(REFERER_CONTEXT_NAME, refererGroups);
context.put(REFERER_CONTEXT_MAX_LENGTH, new Integer(refererLogConfiguration.getRefererMaxLength()));
return entries;
}
}
public void cleanup() throws BlojsomPluginException {
}
public void destroy() throws BlojsomPluginException {
Iterator refererUserIterator = _refererUsers.keySet().iterator();
String user;
while (refererUserIterator.hasNext()) {
user = (String) refererUserIterator.next();
RefererLogConfiguration refererLogConfiguration = (RefererLogConfiguration) _refererUsers.get(user);
Map refererGroups = refererLogConfiguration.getRefererGroups();
String refererlog = refererLogConfiguration.getRefererLog();
Properties refererProperties = new BlojsomProperties();
Iterator groupiterator = refererGroups.keySet().iterator();
while (groupiterator.hasNext()) {
String groupflavor = (String) groupiterator.next();
BlogRefererGroup group = (BlogRefererGroup) refererGroups.get(groupflavor);
if (group.isHitCounter()) {
refererProperties.put(groupflavor + "." + getRefererDate(group.getLastReferralDate()) + "." + group.getReferralCount(), HITCOUNTER_KEY);
} else {
Iterator flavoriterator = group.keySet().iterator();
while (flavoriterator.hasNext()) {
String flavorkey = (String) flavoriterator.next();
BlogReferer referer = (BlogReferer) group.get(flavorkey);
refererProperties.put(groupflavor + "." + getRefererDate(referer.getLastReferral()) + "." + referer.getCount(),
referer.getUrl());
}
}
}
try {
FileOutputStream fos = new FileOutputStream(refererlog, false);
refererProperties.store(fos, REFERER_LOG_HEADER);
fos.close();
} catch (IOException e) {
_logger.error(e);
}
}
}
private static Date getDateFromReferer(String rfcdate) {
Date result = null;
SimpleDateFormat sdf = new SimpleDateFormat(REFERER_DATE_FORMAT);
try {
result = sdf.parse(rfcdate);
} catch (ParseException e) {
result = new Date();
}
return result;
}
public static String getRefererDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat(REFERER_DATE_FORMAT);
return sdf.format(date);
}
private static class RefererLogConfiguration {
private List _blacklistPatterns;
private String _refererLog = null;
private String _blogUrlFilter = null;
private Map _refererGroups;
private List _hitCountFlavors;
private int _refererMaxLength = REFERER_MAX_LENGTH_DEFAULT;
public RefererLogConfiguration(List blacklistPatterns,
String refererLog,
String blogUrlFilter,
Map refererGroups,
List hitCountFlavors,
int refererMaxLength) {
_blacklistPatterns = blacklistPatterns;
_refererLog = refererLog;
_blogUrlFilter = blogUrlFilter;
_refererGroups = refererGroups;
_hitCountFlavors = hitCountFlavors;
_refererMaxLength = refererMaxLength;
}
public List getBlacklistPatterns() {
return _blacklistPatterns;
}
public String getRefererLog() {
return _refererLog;
}
public String getBlogUrlFilter() {
return _blogUrlFilter;
}
public Map getRefererGroups() {
return _refererGroups;
}
public List getHitCountFlavors() {
return _hitCountFlavors;
}
public int getRefererMaxLength() {
return _refererMaxLength;
}
}
}