BlojsomServlet.java [plain text]
package org.blojsom.servlet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.blojsom.BlojsomException;
import org.blojsom.blog.*;
import org.blojsom.dispatcher.BlojsomDispatcher;
import org.blojsom.fetcher.BlojsomFetcher;
import org.blojsom.fetcher.BlojsomFetcherException;
import org.blojsom.plugin.BlojsomPlugin;
import org.blojsom.plugin.BlojsomPluginException;
import org.blojsom.util.BlojsomUtils;
import org.blojsom.util.resources.ResourceManager;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.*;
public class BlojsomServlet extends BlojsomBaseServlet {
private static final String BLOJSOM_DISPATCHER_MAP_CONFIGURATION_IP = "dispatcher-configuration";
private Log _logger = LogFactory.getLog(BlojsomServlet.class);
private Map _plugins;
private Map _dispatchers;
private ResourceManager _resourceManager;
public BlojsomServlet() {
}
protected void configureDispatchers(ServletConfig servletConfig) throws ServletException {
String templateConfiguration = servletConfig.getInitParameter(BLOJSOM_DISPATCHER_MAP_CONFIGURATION_IP);
_dispatchers = new HashMap();
Properties templateMapProperties = new Properties();
InputStream is = servletConfig.getServletContext().getResourceAsStream(templateConfiguration);
try {
templateMapProperties.load(is);
is.close();
Iterator templateIterator = templateMapProperties.keySet().iterator();
while (templateIterator.hasNext()) {
String templateExtension = (String) templateIterator.next();
String templateDispatcherClass = templateMapProperties.getProperty(templateExtension);
Class dispatcherClass = Class.forName(templateDispatcherClass);
BlojsomDispatcher dispatcher = (BlojsomDispatcher) dispatcherClass.newInstance();
dispatcher.init(servletConfig, _blojsomConfiguration);
_dispatchers.put(templateExtension, dispatcher);
_logger.debug("Added template dispatcher: " + templateDispatcherClass);
}
} catch (InstantiationException e) {
_logger.error(e);
} catch (IllegalAccessException e) {
_logger.error(e);
} catch (ClassNotFoundException e) {
_logger.error(e);
} catch (IOException e) {
_logger.error(e);
throw new ServletException(e);
} catch (BlojsomException e) {
_logger.error(e);
throw new ServletException(e);
}
}
protected void configureFlavorsForBlog(ServletConfig servletConfig, BlogUser blogUser) throws ServletException {
String flavorConfiguration = servletConfig.getInitParameter(BLOJSOM_FLAVOR_CONFIGURATION_IP);
if (BlojsomUtils.checkNullOrBlank(flavorConfiguration)) {
flavorConfiguration = DEFAULT_FLAVOR_CONFIGURATION_FILE;
}
Map flavors = new HashMap();
Map flavorToTemplateMap = new HashMap();
Map flavorToContentTypeMap = new HashMap();
String user = blogUser.getId();
Properties flavorProperties = new Properties();
InputStream is = servletConfig.getServletContext().getResourceAsStream(_baseConfigurationDirectory + user + '/' + flavorConfiguration);
try {
flavorProperties.load(is);
is.close();
_logger.debug("Loaded flavor information for user: " + user);
Iterator flavorIterator = flavorProperties.keySet().iterator();
while (flavorIterator.hasNext()) {
String flavor = (String) flavorIterator.next();
String[] flavorMapping = BlojsomUtils.parseCommaList(flavorProperties.getProperty(flavor));
flavors.put(flavor, flavor);
flavorToTemplateMap.put(flavor, flavorMapping[0]);
flavorToContentTypeMap.put(flavor, flavorMapping[1]);
}
blogUser.setFlavors(flavors);
blogUser.setFlavorToTemplate(flavorToTemplateMap);
blogUser.setFlavorToContentType(flavorToContentTypeMap);
} catch (IOException e) {
_logger.error(e);
throw new ServletException(e);
}
}
protected void configurePlugins(ServletConfig servletConfig) throws ServletException {
Properties pluginProperties;
String pluginConfiguration = servletConfig.getInitParameter(BLOJSOM_PLUGIN_CONFIGURATION_IP);
if (BlojsomUtils.checkNullOrBlank(pluginConfiguration)) {
_logger.error("No plugin configuration file specified");
throw new ServletException("No plugin configuration file specified");
}
Iterator pluginIterator;
_plugins = new HashMap();
String pluginConfigurationLocation = _baseConfigurationDirectory + pluginConfiguration;
pluginProperties = new Properties();
try {
pluginProperties = BlojsomUtils.loadProperties(servletConfig, pluginConfigurationLocation);
} catch (BlojsomException e) {
_logger.error(e);
throw new ServletException(e);
}
pluginIterator = pluginProperties.keySet().iterator();
while (pluginIterator.hasNext()) {
String plugin = (String) pluginIterator.next();
if (plugin.indexOf(BLOJSOM_PLUGIN_CHAIN) != -1) {
_logger.debug("Skipping blojsom plugin chain in global plugin configuration file");
} else {
String pluginClassName = pluginProperties.getProperty(plugin);
try {
Class pluginClass = Class.forName(pluginClassName);
BlojsomPlugin blojsomPlugin = (BlojsomPlugin) pluginClass.newInstance();
blojsomPlugin.init(servletConfig, _blojsomConfiguration);
_plugins.put(plugin, blojsomPlugin);
_logger.info("Added blojsom plugin: " + pluginClassName);
} catch (BlojsomPluginException e) {
_logger.error(e);
} catch (InstantiationException e) {
_logger.error(e);
} catch (IllegalAccessException e) {
_logger.error(e);
} catch (ClassNotFoundException e) {
_logger.error(e);
}
}
}
}
protected void configurePluginsForBlog(ServletConfig servletConfig, BlogUser blogUser) throws ServletException {
Properties pluginProperties;
String pluginConfiguration = servletConfig.getInitParameter(BLOJSOM_PLUGIN_CONFIGURATION_IP);
Iterator pluginIterator = _plugins.keySet().iterator();
if (BlojsomUtils.checkNullOrBlank(pluginConfiguration)) {
_logger.error("No plugin configuration file specified");
throw new ServletException("No plugin configuration file specified");
}
Map pluginChainMap = new HashMap();
String user = blogUser.getId();
InputStream is = servletConfig.getServletContext().getResourceAsStream(_baseConfigurationDirectory + user + '/' + pluginConfiguration);
pluginProperties = new Properties();
try {
pluginProperties.load(is);
is.close();
pluginIterator = pluginProperties.keySet().iterator();
while (pluginIterator.hasNext()) {
String plugin = (String) pluginIterator.next();
if (plugin.indexOf(BLOJSOM_PLUGIN_CHAIN) != -1) {
pluginChainMap.put(plugin, BlojsomUtils.parseCommaList(pluginProperties.getProperty(plugin)));
_logger.debug("Added plugin chain: " + plugin + '=' + pluginProperties.getProperty(plugin) + " for user: " + user);
}
}
blogUser.setPluginChain(pluginChainMap);
} catch (IOException e) {
_logger.error(e);
throw new ServletException(e);
}
}
protected void configureResourceManager() throws ServletException {
String resourceManagerClass = _blojsomConfiguration.getResourceManager();
try {
Class resourceManagerClazz = Class.forName(resourceManagerClass);
_resourceManager = (ResourceManager) resourceManagerClazz.newInstance();
_resourceManager.init(_blojsomConfiguration);
} catch (InstantiationException e) {
_logger.error(e);
throw new ServletException(e);
} catch (IllegalAccessException e) {
_logger.error(e);
throw new ServletException(e);
} catch (ClassNotFoundException e) {
_logger.error(e);
throw new ServletException(e);
} catch (BlojsomException e) {
_logger.error(e);
throw new ServletException(e);
}
}
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
configureBlojsom(servletConfig);
configureDispatchers(servletConfig);
configurePlugins(servletConfig);
configureResourceManager();
_logger.debug("blojsom: All Your Blog Are Belong To Us");
}
protected void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
try {
httpServletRequest.setCharacterEncoding(UTF8);
} catch (UnsupportedEncodingException e) {
_logger.error(e);
}
if (!httpServletRequest.getRequestURI().endsWith("/")) {
StringBuffer redirectURL = new StringBuffer();
redirectURL.append(httpServletRequest.getRequestURI());
redirectURL.append("/");
if (httpServletRequest.getParameterMap().size() > 0) {
redirectURL.append("?");
redirectURL.append(BlojsomUtils.convertRequestParams(httpServletRequest));
}
_logger.debug("Redirecting the user to: " + redirectURL.toString());
httpServletResponse.sendRedirect(redirectURL.toString());
return;
}
String user = httpServletRequest.getParameter("id");
if (BlojsomUtils.checkNullOrBlank(user)) {
String userFromPath = BlojsomUtils.getUserFromPath(httpServletRequest.getPathInfo());
if (userFromPath == null) {
user = _blojsomConfiguration.getDefaultUser();
} else {
user = userFromPath;
}
}
BlogUser blogUser = null;
try {
blogUser = _blojsomConfiguration.loadBlog(user);
} catch (BlojsomException e) {
if (!BlojsomUtils.checkNullOrBlank(_blojsomConfiguration.getDefaultUser())) {
try {
blogUser = _blojsomConfiguration.loadBlog(_blojsomConfiguration.getDefaultUser());
} catch (BlojsomException e2) {
_logger.error(e2);
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "Requested blog not found: " + user);
return;
}
}
}
if (!_blojsomConfiguration.checkBlogIDExists(blogUser.getId())) {
_blojsomConfiguration.addBlogID(blogUser.getId());
}
if (!_blojsomConfiguration.checkBlogIDExists(blogUser.getId())) {
_blojsomConfiguration.addBlogID(blogUser.getId());
}
configureFlavorsForBlog(_servletConfig, blogUser);
configurePluginsForBlog(_servletConfig, blogUser);
Blog blog = blogUser.getBlog();
BlojsomUtils.resolveDynamicBaseAndBlogURL(httpServletRequest, blog, user);
String flavor = httpServletRequest.getParameter(FLAVOR_PARAM);
if (BlojsomUtils.checkNullOrBlank(flavor)) {
flavor = blog.getBlogDefaultFlavor();
if (blogUser.getFlavors().get(flavor) == null) {
flavor = DEFAULT_FLAVOR_HTML;
}
} else {
if (blogUser.getFlavors().get(flavor) == null) {
flavor = blog.getBlogDefaultFlavor();
if (blogUser.getFlavors().get(flavor) == null) {
flavor = DEFAULT_FLAVOR_HTML;
}
}
}
HashMap context = new HashMap();
context.put(BLOJSOM_RESOURCE_MANAGER_CONTEXT_KEY, _resourceManager);
context.put(BLOJSOM_REQUESTED_FLAVOR, flavor);
BlogEntry[] entries = null;
BlogCategory[] categories = null;
try {
categories = _fetcher.fetchCategories(httpServletRequest, httpServletResponse, blogUser, flavor, context);
entries = _fetcher.fetchEntries(httpServletRequest, httpServletResponse, blogUser, flavor, context);
} catch (BlojsomFetcherException e) {
_logger.error(e);
}
String[] pluginChain = null;
Map pluginChainMap = blogUser.getPluginChain();
if (httpServletRequest.getParameter(PLUGINS_PARAM) != null) {
pluginChain = BlojsomUtils.parseCommaList(httpServletRequest.getParameter(PLUGINS_PARAM));
} else {
String pluginChainMapKey = flavor + '.' + BLOJSOM_PLUGIN_CHAIN;
String[] pluginChainValue = (String[]) pluginChainMap.get(pluginChainMapKey);
if (pluginChainValue != null && pluginChainValue.length > 0) {
pluginChain = (String[]) pluginChainMap.get(pluginChainMapKey);
} else {
pluginChain = (String[]) pluginChainMap.get(BLOJSOM_PLUGIN_CHAIN);
}
}
if ((entries != null) && (pluginChain != null) && (!"".equals(pluginChain))) {
for (int i = 0; i < pluginChain.length; i++) {
String plugin = pluginChain[i];
if (_plugins.containsKey(plugin)) {
BlojsomPlugin blojsomPlugin = (BlojsomPlugin) _plugins.get(plugin);
_logger.debug("blojsom plugin execution: " + blojsomPlugin.getClass().getName());
try {
entries = blojsomPlugin.process(httpServletRequest, httpServletResponse, blogUser, context, entries);
blojsomPlugin.cleanup();
} catch (BlojsomPluginException e) {
_logger.error(e);
}
} else {
_logger.error("No plugin loaded for: " + plugin);
}
}
}
String blogdate = null;
String blogISO8601Date = null;
String blogUTCDate = null;
Date blogDateObject = null;
boolean sendLastModified = true;
if (httpServletRequest.getParameter(OVERRIDE_LASTMODIFIED_PARAM) != null) {
sendLastModified = Boolean.getBoolean(httpServletRequest.getParameter(OVERRIDE_LASTMODIFIED_PARAM));
}
if (sendLastModified) {
if ((entries != null) && (entries.length > 0)) {
BlogEntry _entry = entries[0];
long _lastmodified;
if (_entry.getNumComments() > 0) {
BlogComment _comment = _entry.getCommentsAsArray()[_entry.getNumComments() - 1];
_lastmodified = _comment.getCommentDateLong();
_logger.debug("Adding last-modified header for most recent entry comment");
} else {
_lastmodified = _entry.getLastModified();
_logger.debug("Adding last-modified header for most recent blog entry");
}
if (context.containsKey(BLOJSOM_LAST_MODIFIED)) {
Long lastModified = (Long) context.get(BLOJSOM_LAST_MODIFIED);
if (lastModified.longValue() > _lastmodified) {
_lastmodified = lastModified.longValue();
}
}
String etagLastModified = BlojsomUtils.getISO8601Date(new Date(_lastmodified));
httpServletResponse.addHeader(HTTP_ETAG, "\"" + BlojsomUtils.digestString(etagLastModified) + "\"");
httpServletResponse.addDateHeader(HTTP_LASTMODIFIED, _lastmodified);
blogdate = entries[0].getRFC822Date();
blogISO8601Date = entries[0].getISO8601Date();
blogDateObject = entries[0].getDate();
blogUTCDate = BlojsomUtils.getUTCDate(entries[0].getDate());
} else {
_logger.debug("Adding last-modified header for current date");
Date today = new Date();
blogdate = BlojsomUtils.getRFC822Date(today);
blogISO8601Date = BlojsomUtils.getISO8601Date(today);
blogUTCDate = BlojsomUtils.getUTCDate(today);
blogDateObject = today;
httpServletResponse.addDateHeader(HTTP_LASTMODIFIED, today.getTime());
httpServletResponse.addHeader(HTTP_ETAG, "\"" + BlojsomUtils.digestString(blogISO8601Date) + "\"");
}
}
context.put(BLOJSOM_DATE, blogdate);
context.put(BLOJSOM_DATE_ISO8601, blogISO8601Date);
context.put(BLOJSOM_DATE_OBJECT, blogDateObject);
context.put(BLOJSOM_DATE_UTC, blogUTCDate);
context.put(BLOJSOM_BLOG, blog);
context.put(BLOJSOM_SITE_URL, blog.getBlogBaseURL());
context.put(BLOJSOM_ENTRIES, entries);
context.put(BLOJSOM_CATEGORIES, categories);
context.put(BLOJSOM_COMMENTS_ENABLED, blog.getBlogCommentsEnabled());
context.put(BLOJSOM_VERSION, BLOJSOM_VERSION_NUMBER);
context.put(BLOJSOM_USER, blogUser.getId());
context.put(BLOJSOM_PLUGINS, Collections.unmodifiableMap(_plugins));
String flavorTemplate;
Map flavorToTemplate = blogUser.getFlavorToTemplate();
if (flavorToTemplate.get(flavor) == null) {
flavorTemplate = (String) flavorToTemplate.get(DEFAULT_FLAVOR_HTML);
} else {
flavorTemplate = (String) flavorToTemplate.get(flavor);
}
Map flavorToContentType = blogUser.getFlavorToContentType();
String flavorContentType = (String) flavorToContentType.get(flavor);
String templateExtension = BlojsomUtils.getFileExtension(flavorTemplate);
_logger.debug("Template extension: " + templateExtension);
BlojsomDispatcher dispatcher = (BlojsomDispatcher) _dispatchers.get(templateExtension);
dispatcher.dispatch(httpServletRequest, httpServletResponse, blogUser, context, flavorTemplate, flavorContentType);
}
public void destroy() {
super.destroy();
try {
_fetcher.destroy();
} catch (BlojsomFetcherException e) {
_logger.error(e);
}
Iterator pluginIteratorIterator = _plugins.keySet().iterator();
while (pluginIteratorIterator.hasNext()) {
String pluginName = (String) pluginIteratorIterator.next();
BlojsomPlugin plugin = (BlojsomPlugin) _plugins.get(pluginName);
try {
plugin.destroy();
_logger.debug("Removed blojsom plugin: " + plugin.getClass().getName());
} catch (BlojsomPluginException e) {
_logger.error(e);
}
}
_logger.debug("blojsom destroyed");
}
}