You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2005/10/21 23:46:28 UTC
svn commit: r327589 [28/72] - in /incubator/roller/branches/roller_1.x: ./
contrib/ contrib/lib/ contrib/plugins/ contrib/plugins/src/
contrib/plugins/src/org/ contrib/plugins/src/org/roller/
contrib/plugins/src/org/roller/presentation/ contrib/plugins...
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/ArchiveParser.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/ArchiveParser.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/ArchiveParser.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/ArchiveParser.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,428 @@
+/*
+ * Created on Apr 2, 2004
+ */
+package org.roller.presentation;
+
+
+/**
+ * TODO: revisit this class once Atom 1.0 support comes to Rome
+ * @author lance.lavandowska
+ */
+public class ArchiveParser
+{
+// protected static final Log mLogger =
+// LogFactory.getFactory().getInstance(ArchiveParser.class);
+//
+// private Roller roller;
+// private WebsiteData website;
+// private File archiveFile;
+//
+// private Timestamp current;
+//
+// private WeblogCategoryData defaultCategory;
+//
+// private WeblogCategoryData rootCategory;
+//
+// private IndexManager indexMgr;
+//
+//
+// /**
+// * @param rreq
+// * @param f
+// */
+// public ArchiveParser(Roller roller, WebsiteData website, File f) throws RollerException
+// {
+// this.roller = roller;
+// this.website = website;
+// archiveFile = f;
+//
+// current = new Timestamp( System.currentTimeMillis());
+// defaultCategory = website.getDefaultCategory();
+// rootCategory = roller.getWeblogManager().getRootWeblogCategory(website);
+// indexMgr = roller.getIndexManager();
+// }
+//
+// public String parse() throws RollerException
+// {
+// StringBuffer buf = new StringBuffer();
+//
+// // parse file and convert to WeblogEntryDatas
+// Feed atomFeed = getAtomFeed();
+// if (atomFeed != null)
+// {
+// importAtom(buf, atomFeed);
+// }
+// else
+// {
+// // not an Atom feed, try RSS
+// ChannelIF channel = getInformaChannel();
+//
+// if (channel != null && channel.getItems()!= null)
+// {
+// importRSS(buf, channel);
+// }
+// }
+//
+// return buf.toString();
+// }
+//
+// /**
+// * @return
+// * @throws FileNotFoundException
+// * @throws IOException
+// */
+// private Feed getAtomFeed()
+// {
+// Feed feed = null;
+// BufferedInputStream bis = null;
+// try
+// {
+// FileInputStream fis = new FileInputStream(archiveFile);
+// bis = new BufferedInputStream(fis);
+// // we need AtomFeedReader for Roller-specific elements
+// AtomFeedReader reader = new AtomFeedReader(bis);
+// // current 'version' of Atom4J parses on init, next version won't
+// if (reader.getFeed() == null)
+// {
+// reader.parse();
+// }
+// feed = reader.getFeed();
+// }
+// catch (FileNotFoundException e)
+// {
+// mLogger.debug("You told me to read a non-existant file.", e);
+// }
+// catch (IOException e)
+// {
+// mLogger.debug("Digester throws IOException for no reason I can tell.", e);
+// }
+// finally
+// {
+// try
+// {
+// if (bis != null) bis.close();
+// }
+// catch (IOException e1)
+// {
+// mLogger.error("Unable to close stream to " + archiveFile);
+// }
+// }
+// return feed;
+// }
+//
+// /**
+// * @param channel
+// * @return
+// */
+// private ChannelIF getInformaChannel()
+// {
+// ChannelIF channel = null;
+// BufferedInputStream bis = null;
+// try
+// {
+// FileInputStream fis = new FileInputStream(archiveFile);
+// bis = new BufferedInputStream(fis);
+// channel = RSSParser.parse(new ChannelBuilder(), bis);
+// }
+// catch (FileNotFoundException e)
+// {
+// e.printStackTrace();
+// }
+// catch (IOException e)
+// {
+// e.printStackTrace();
+// }
+// catch (ParseException e)
+// {
+// e.printStackTrace();
+// }
+// finally
+// {
+// try
+// {
+// if (bis != null) bis.close();
+// }
+// catch (IOException e1)
+// {
+// mLogger.error("Unable to close stream to " + archiveFile);
+// }
+// }
+// return channel;
+// }
+//
+// /**
+// *
+// */
+// private void importAtom(StringBuffer buf, Feed atomFeed) throws RollerException
+// {
+// AtomEntry atomEntry;
+// WeblogEntryData entry = null;
+// HashMap entryMap = new HashMap(); // map of Roller entries
+// WeblogCategoryData category;
+// HashMap categoryMap = new HashMap();
+// categoryMap.put("defaultCategory", defaultCategory);
+// Collection entries = atomFeed.getEntries();
+// if (entries != null)
+// {
+// Iterator it = entries.iterator();
+// while (it.hasNext())
+// {
+// entry = null; //reset
+//
+// // create new Entry from AtomEntry
+// atomEntry = (AtomEntry)it.next();
+//
+// // test to see if this Entry is a Comment (it's
+// // parent should already exist).
+// /* Added by Roller's AtomEntry */
+// if (atomEntry.getAnnotation() != null)
+// {
+// createComment(atomEntry, entryMap);
+// continue;
+// }
+//
+// if (atomEntry.getId() != null)
+// {
+// entry = roller.getWeblogManager().retrieveWeblogEntry(atomEntry.getId());
+// }
+// if (entry == null)
+// {
+// category = null;
+// /* Atom doesn't currently have a Category definition.
+// Added by Roller's AtomEntry */
+// // return WeblogCategoryData for getCategories
+// if (atomEntry.getCategories() != null)
+// {
+// Iterator cIt = atomEntry.getCategories().iterator();
+// if (cIt.hasNext())
+// {
+// String catPath = (String)cIt.next();
+// category = locateCategory(catPath, categoryMap);
+// }
+// }
+// if (category == null) category = defaultCategory;
+//
+// entry = entryFromAtom(buf, atomEntry, entryMap, category);
+//
+// indexEntry(entry);
+// }
+// else
+// {
+// entryMap.put(entry.getId(), entry);
+// buf.append("An Entry already exists for id: " + atomEntry.getId() + ".<br />");
+// }
+// }
+// }
+// }
+//
+// /**
+// * Convert an AtomEntry to a WeblogEntryData.
+// * @param buf
+// * @param atomEntry
+// * @param entryMap
+// * @param category
+// * @return
+// * @throws RollerException
+// */
+// private WeblogEntryData entryFromAtom(StringBuffer buf, AtomEntry atomEntry, HashMap entryMap, WeblogCategoryData category) throws RollerException
+// {
+// System.out.println(atomEntry);
+// String title = atomEntry.getTitle().getText();
+// String content = "";
+// Date issued = new Date(current.getTime());
+// Date modified = new Date(current.getTime());
+// String id = atomEntry.getId();
+// if (atomEntry.getContent() != null)
+// {
+// content = atomEntry.getContent().getText();
+// }
+// if (atomEntry.getIssued() != null) issued = atomEntry.getIssued();
+// if (atomEntry.getModified()!= null) modified = atomEntry.getModified();
+//
+// WeblogEntryData entry = new WeblogEntryData(
+// null, category, website,
+// title, (String)null,
+// content, (String)null,
+// new Timestamp(issued.getTime()),
+// new Timestamp(modified.getTime()),
+// Boolean.TRUE);
+// entry.save();
+// // store entry in local cache for Comments' to lookup
+// if (id == null) id = entry.getId();
+// entryMap.put(id, entry);
+//
+// buf.append("\"").append(title).append("\" imported.<br />\n");
+// return entry;
+// }
+//
+// /**
+// * @param atomEntry
+// * @param entryMap
+// */
+// private void createComment(AtomEntry atomEntry, HashMap entryMap) throws RollerException
+// {
+// // first try to get the Entry from local cache
+// CommentData comment = roller.getWeblogManager().retrieveComment(atomEntry.getId());
+// if (comment == null)
+// {
+// String entryId = atomEntry.getAnnotation();
+// WeblogEntryData entry = (WeblogEntryData) entryMap.get(entryId);
+// if (entry == null)
+// {
+// // now try getting it from database
+// entry = roller.getWeblogManager().retrieveWeblogEntry(entryId);
+// }
+// if (entry != null)
+// {
+// comment = new CommentData(
+// null,
+// entry,
+// atomEntry.getAuthor().getName(),
+// atomEntry.getAuthor().getEmail(),
+// atomEntry.getAuthor().getUrl(),
+// atomEntry.getContent().getText(),
+// new Timestamp(atomEntry.getIssued().getTime()),
+// Boolean.FALSE, Boolean.FALSE);
+// comment.save();
+// }
+// else
+// {
+// mLogger.warn("Unable to find parent WeblogEntry for id: " + entryId +
+// ".\n\tComment not created: " + atomEntry.getTitle().getText());
+// }
+// }
+// else
+// {
+// mLogger.info("A Comment already exists for id: " + atomEntry.getId());
+// }
+// }
+//
+// /**
+// * @param rreq
+// * @param buf
+// * @param channel
+// * @throws RollerException
+// */
+// private void importRSS(StringBuffer buf, ChannelIF channel) throws RollerException
+// {
+// ItemIF item;
+// WeblogEntryData entry = null;
+// WeblogCategoryData category;
+// HashMap categoryMap = new HashMap();
+// categoryMap.put("defaultCategory", defaultCategory);
+// Iterator it = channel.getItems().iterator();
+// while (it.hasNext())
+// {
+// entry = null; //reset
+// item = (ItemIF)it.next();
+//
+// if (item.getGuid() != null && !item.getGuid().isPermaLink())
+// {
+// entry = roller.getWeblogManager().retrieveWeblogEntry(item.getGuid().getLocation());
+// }
+//
+// if (entry == null)
+// {
+// category = null;
+// // return WeblogCategoryData for getCategories
+// if (item.getCategories() != null)
+// {
+// Iterator cIt = item.getCategories().iterator();
+// if (cIt.hasNext())
+// {
+// // see if we've already created a category for this String
+// CategoryIF catIF = (CategoryIF)cIt.next();
+// category = locateCategory(catIF.getTitle(), categoryMap);
+// }
+// }
+// if (category == null) category = defaultCategory;
+//
+// entry = entryFromRSS(buf, item, category);
+//
+// indexEntry(entry);
+// }
+// else
+// {
+// buf.append("An Entry already exists for id: " + entry.getId() + ".<br />");
+// }
+// }
+// }
+//
+// /**
+// * @param entry
+// */
+// private void indexEntry(WeblogEntryData entry) throws RollerException
+// {
+// // index the new Entry
+// indexMgr.addEntryIndexOperation(entry);
+// }
+//
+// /**
+// * Convert an RSS Item to a WeblogEntryData.
+// * @param buf
+// * @param item
+// * @param category
+// * @return
+// * @throws RollerException
+// */
+// private WeblogEntryData entryFromRSS(StringBuffer buf, ItemIF item, WeblogCategoryData category) throws RollerException
+// {
+// WeblogEntryData entry;
+// // make sure there is an item date
+// if (item.getDate() == null)
+// {
+// item.setDate(new Date(current.getTime()));
+// }
+//
+// entry = new WeblogEntryData(
+// (String)null, category, website,
+// item.getTitle(), (String)null,
+// item.getDescription(), (String)null,
+// new Timestamp(item.getDate().getTime()),
+// new Timestamp(item.getDate().getTime()),
+// Boolean.TRUE);
+// entry.save();
+// buf.append("\"").append(item.getTitle()).append("\" imported.<br />\n");
+// return entry;
+// }
+//
+// /**
+// * Iterate over Item's Categories, if any, using the first one.
+// * Try to match against any we've already pulled.
+// * If none found locally, check against the database.
+// * If we still don't find a match, create one and store it locally.
+// * If there are no Item Categories, use defaultCategory
+// *
+// * @param mapping
+// * @param actionForm
+// * @param request
+// * @param response
+// * @return
+// * @throws IOException
+// * @throws ServletException
+// */
+// private WeblogCategoryData locateCategory(
+// String catName, HashMap categoryMap)
+// throws RollerException
+// {
+// WeblogCategoryData category = (WeblogCategoryData)categoryMap.get(catName);
+// if (category == null) // not in local map
+// {
+// // look for it in database, by path
+// category = roller.getWeblogManager()
+// .getWeblogCategoryByPath(website, category, catName);
+//
+// if (category == null) // not in database
+// {
+// // create a new one
+// category = new WeblogCategoryData(null,
+// website, rootCategory,
+// catName, catName, null);
+// category.save();
+// }
+// categoryMap.put(catName, category);
+// }
+//
+// return category;
+// }
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/Authenticator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/Authenticator.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/Authenticator.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/Authenticator.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,15 @@
+
+package org.roller.presentation;
+
+import javax.servlet.http.HttpServletRequest;
+
+/** Interface used by Roller to check user authentication and role */
+public interface Authenticator
+{
+/** Return the name of the request's authenticated user, or null if none */
+public String getAuthenticatedUserName( HttpServletRequest req );
+
+/** Return true if authenticated user is in the specified role */
+public boolean isAuthenticatedUserInRole( HttpServletRequest req, String role);
+}
+
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/BasePageModel.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/BasePageModel.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/BasePageModel.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/BasePageModel.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,96 @@
+/*
+ * Created on Mar 10, 2004
+ */
+package org.roller.presentation;
+
+import org.apache.struts.action.ActionMapping;
+import org.roller.RollerException;
+import org.roller.pojos.UserData;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Re-usable base for page models.
+ * @author David M Johnson
+ */
+public class BasePageModel
+{
+ private HttpServletRequest request = null;
+ private HttpServletResponse response = null;
+ private ActionMapping mapping = null;
+
+ public BasePageModel(
+ HttpServletRequest request,
+ HttpServletResponse response,
+ ActionMapping mapping)
+ {
+ this.request = request;
+ this.response = response;
+ this.mapping = mapping;
+ }
+
+ public String getBaseURL()
+ {
+ return request.getContextPath();
+ }
+
+ public String getShortDateFormat()
+ {
+ DateFormat sdf = DateFormat.getDateInstance(
+ DateFormat.SHORT, request.getLocale());
+ if (sdf instanceof SimpleDateFormat)
+ {
+ return ((SimpleDateFormat)sdf).toLocalizedPattern();
+ }
+ return "yyyy/MM/dd";
+ }
+
+ public String getMediumDateFormat()
+ {
+ DateFormat sdf = DateFormat.getDateInstance(
+ DateFormat.MEDIUM, request.getLocale());
+ if (sdf instanceof SimpleDateFormat)
+ {
+ return ((SimpleDateFormat)sdf).toLocalizedPattern();
+ }
+ return "MMM dd, yyyy";
+ }
+
+ public UserData getUser()
+ {
+ return RollerRequest.getRollerRequest(request).getUser();
+ }
+
+ /**
+ * @return Returns the mapping.
+ */
+ public ActionMapping getMapping()
+ {
+ return mapping;
+ }
+
+ /**
+ * @return Returns the request.
+ */
+ public HttpServletRequest getRequest()
+ {
+ return request;
+ }
+
+ /**
+ * @return Returns the response.
+ */
+ public HttpServletResponse getResponse()
+ {
+ return response;
+ }
+
+ public boolean getIsAdmin() throws RollerException
+ {
+ return RollerRequest.getRollerRequest(request).isAdminUser();
+ }
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/BlacklistUpdateTask.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/BlacklistUpdateTask.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/BlacklistUpdateTask.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/BlacklistUpdateTask.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,32 @@
+/*
+ * Created on Mar 10, 2004
+ */
+package org.roller.presentation;
+
+import java.util.TimerTask;
+
+import org.roller.RollerException;
+import org.roller.model.Roller;
+import org.roller.model.RollerFactory;
+import org.roller.model.ScheduledTask;
+import org.roller.util.Blacklist;
+
+/**
+ * @author lance.lavandowska
+ */
+public class BlacklistUpdateTask extends TimerTask implements ScheduledTask
+{
+ public void run()
+ {
+ // try reading new def from URL
+ Blacklist.checkForUpdate();
+ }
+ public void init(Roller roller, String realPath) throws RollerException
+ {
+ // load Blacklist from file
+ String uploadDir = RollerFactory.getRoller().getFileManager().getUploadDir();
+ Blacklist.getBlacklist(null, uploadDir);
+ // now have it check for an update
+ Blacklist.checkForUpdate();
+ }
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/DefaultAuthenticator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/DefaultAuthenticator.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/DefaultAuthenticator.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/DefaultAuthenticator.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,30 @@
+
+package org.roller.presentation;
+
+import java.security.Principal;
+
+import javax.servlet.http.HttpServletRequest;
+
+
+/** Class used by Roller to check user authentication and role */
+public class DefaultAuthenticator implements Authenticator
+{
+ /** Return the name of the request's authenticated user, or null if none */
+ public String getAuthenticatedUserName( HttpServletRequest req )
+ {
+ String ret = null;
+ Principal prince = req.getUserPrincipal();
+ if ( prince != null )
+ {
+ ret = prince.getName();
+ }
+ return ret;
+ }
+
+ /** Return true if authenticated user is in the specified role */
+ public boolean isAuthenticatedUserInRole(HttpServletRequest req,String role)
+ {
+ return req.isUserInRole( role );
+ }
+}
+
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/LanguageUtil.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/LanguageUtil.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/LanguageUtil.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/LanguageUtil.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,268 @@
+/*
+ * Filename: LanguageUtil.java
+ *
+ * Created on 04-May-04
+ */
+package org.roller.presentation;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.Globals;
+import org.roller.pojos.WebsiteData;
+
+/**
+ * This class provides utility methods to deal with
+ * multiple languages and other i18n stuff.
+ *
+ * @author <a href="mailto:molen@mail.com">Jaap van der Molen</a>
+ * @version $Revision: 1.8 $
+ */
+public class LanguageUtil
+{
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(LanguageUtil.class);
+
+ /**
+ * reference to supported languages
+ */
+ public static final String SUPPORTED_LANGUAGES =
+ "org.roller.presentation.supported.languages";
+
+ /**
+ * Extracts langauges from the ServletContext. If
+ * not present, returns null.
+ *
+ * @param ctx
+ * @return
+ */
+ public static Locale[] getSupportedLanguages(ServletContext ctx)
+ {
+ return (Locale[]) ctx.getAttribute(SUPPORTED_LANGUAGES);
+ }
+
+ /**
+ * Tests if a language is supported by roller as configured
+ * in the LanguageServlet init paramater.
+ *
+ * @param lang
+ * @param ctx
+ * @return
+ */
+ public static boolean isSupported(String lang, ServletContext ctx)
+ {
+ return isSupported(createLocale(lang), ctx);
+ }
+
+ /**
+ * Tests if a language is supported by roller as configured
+ * in the LanguageServlet init paramater.
+ *
+ * If no supported languages are available, false is returned.
+ *
+ * @param locale
+ * @param ctx
+ * @return
+ */
+ public static boolean isSupported(Locale locale, ServletContext ctx)
+ {
+ mLogger.debug("isSupported( locale = "+locale+" )");
+ boolean isSupported = false;
+ Locale[] supportedLanguages = getSupportedLanguages(ctx);
+
+ if (supportedLanguages == null)
+ {
+ return false;
+ }
+
+ for (int i=0; i<supportedLanguages.length; i++)
+ {
+ Locale l = (Locale) supportedLanguages[i];
+ if (l.equals(locale)) {
+ isSupported = true;
+ break;
+ } else {
+ Locale langOnly = new Locale(locale.getLanguage());
+ if (l.equals(langOnly)) {
+ isSupported = true;
+ break;
+ }
+ }
+ }
+
+ return isSupported;
+ }
+
+ /**
+ * This method returns the Locale in which the current viewer wants
+ * to view the website. This 'View Locale' is derived as follows:
+ * <ul>
+ * <li>look for existing Locale in Session</li>
+ * <li>if not available, get Locale from request</li>
+ * <li>if not available, use {@link org.roller.presentation.LanguageUtil.getDefaultLocale()}
+ * (= Locale from <code>WebsiteData</code>)</li>
+ * <li>if a Locale is available in the request, verify it against the locales that
+ * are supported by Roller; if it is not supported replace it with the default Locale</li>
+ *
+ * The reason why I don't want to resort to the standard default mechanism of the
+ * Java ResourceBundles, is that this only works for the messages and not for
+ * other things like the dates and calendars (standard Java classes supports all locales).
+ * I think it looks silly to have the dates and calendars appear in French (e.g.) while
+ * the messages appear in English.
+ *
+ * @param request
+ * @return
+ */
+ public static Locale getViewLocale(HttpServletRequest request)
+ {
+ mLogger.debug("getViewLocale()");
+ Locale viewLocale = null;
+
+ // if user is logged in and the user looking at his own website, take website-locale
+ if (isWebsiteOfPrincipal(request))
+ {
+ viewLocale = getDefaultLocale(request);
+ mLogger.debug("websiteLocale = "+viewLocale);
+ }
+ else if (request.getSession(false) != null)
+ {
+ // check session for existing Locale
+ viewLocale = (Locale) request.getSession().getAttribute(Globals.LOCALE_KEY);
+ mLogger.debug("sessionLocale = "+viewLocale);
+ }
+
+ // if not found, look in many places
+ if (viewLocale == null)
+ {
+ // get from request
+ viewLocale = request.getLocale();
+ mLogger.debug("requestLocale = "+viewLocale);
+
+ //still not there? take default
+ if (viewLocale == null)
+ {
+ viewLocale = getDefaultLocale(request);
+ mLogger.debug("defaultLocale = "+viewLocale);
+ }
+ }
+
+ /*
+ * If viewLocale is not supported, switch back to default.
+ *
+ * Note: I do this here under the assumption
+ * that the Locale in the Session is always supported. So,
+ * no checks on the Session Locale.
+ */
+ ServletContext ctx = RollerContext.getServletContext();
+ if (!LanguageUtil.isSupported(viewLocale, ctx))
+ {
+ viewLocale = Locale.getDefault();
+ }
+ mLogger.debug("return Locale = "+viewLocale);
+
+ // add to session (for Velocity text tool)
+ request.getSession().setAttribute(Globals.LOCALE_KEY, viewLocale);
+ return viewLocale;
+ }
+
+ /**
+ * Returns the default website locale using <code>WebsiteData.getLocaleInstance()</code> and
+ * returns <code>null</code> if the WebsiteData object is <code>null</code>.
+ *
+ * Note: This <code>null</code> situation occurs if a User logs in, but his or her website has
+ * been disabled. The website data is not loaded in that case.
+ *
+ * @param request
+ * @return
+ */
+ public static Locale getDefaultLocale(HttpServletRequest request) {
+ mLogger.debug("getDefaultLocale()");
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ WebsiteData website = rreq.getWebsite();
+ if (website==null) {
+ return null;
+ } else {
+ return website.getLocaleInstance();
+ }
+ }
+
+ /**
+ * Verifies if the user is logged in and if so, if the website he
+ * is currently viewing, is the user's website. In that case, true is returned.
+ * Otherwise false.
+ *
+ * The reason for this additional check is that I only want to enforce the
+ * user's own locale if he at his own website. If I didn't, a logged-in user would be forced to
+ * view other sites in their default locale. That could lead to confusing situations.
+ *
+ * TODO: Maybe what I am saying is: shouldn't we store the user's locale as the user's locale,
+ * instead of as the website's locale?
+ *
+ * @param request
+ * @return
+ */
+ public static boolean isWebsiteOfPrincipal(HttpServletRequest request) {
+ boolean result = false;
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ if (rreq != null) {
+ WebsiteData website = rreq.getWebsite();
+ Principal principal = request.getUserPrincipal();
+ if (website != null && principal != null) {
+ return website.getUser().getUserName().equals(principal.getName());
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Helper method to convert a language string to a <code>Locale</code> object.
+ * Example language stringds are 'en' or 'en_US'.
+ *
+ * @param lang
+ * @return
+ */
+ public static Locale createLocale(String lang) {
+ mLogger.debug("createLocale( lang = "+lang+" )");
+ Locale l = null;
+ if (lang.indexOf("_")>0) {
+ String tmpLang = lang.substring(0, lang.indexOf("_"));
+ String tmpCoun = lang.substring(lang.indexOf("_")+1, lang.length());
+ l = new Locale(tmpLang, tmpCoun);
+ } else
+ {
+ l = new Locale(lang);
+ }
+ return l;
+ }
+
+ /**
+ * Helper method to extract a collection of <code>Locale</code> from the
+ * supported languages config string for the LanguageServlet.
+ *
+ * @param supportedLanguages
+ * @return
+ */
+ public static Locale[] extractLanguages(String supportedLanguages) {
+ mLogger.debug("extractLanguages( lang = "+supportedLanguages+" )");
+
+ Vector langs = new Vector();
+ StringTokenizer st = new StringTokenizer(supportedLanguages, ",");
+ while (st.hasMoreTokens())
+ {
+ Locale l = LanguageUtil.createLocale(st.nextToken());
+ langs.add(l);
+ }
+ mLogger.debug("supported languages: "+langs);
+
+ return (Locale[]) langs.toArray(new Locale[langs.size()]);
+ }
+
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/LoginServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/LoginServlet.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/LoginServlet.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/LoginServlet.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,225 @@
+package org.roller.presentation;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.presentation.util.SslUtil;
+import org.roller.util.Utilities;
+
+import java.io.IOException;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.roller.config.RollerConfig;
+
+
+
+/**
+ * Implementation of <strong>HttpServlet</strong> that is used
+ * to get a username and password and mEncrypt the password
+ * before sending to container-managed authentication.
+ *
+ * <p><a href="LoginServlet.java.html"><i>View Source</i></a></p>
+ *
+ * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
+ * @version $Revision: 1.19 $ $Date: 2005/06/07 18:30:18 $
+ *
+ * @web.servlet
+ * display-name="Login Servlet"
+ * load-on-startup="3"
+ * name="login"
+ *
+ * @web.servlet-init-param
+ * name="authURL"
+ * value="/j_security_check"
+ *
+ * @web.servlet-mapping
+ * url-pattern="/auth/*"
+ */
+public class LoginServlet extends HttpServlet
+{
+ static final long serialVersionUID = 8054268881470797053L;
+
+ protected static String mAuthURL = "/j_security_check";
+ protected static String mAlgorithm = "SHA";
+ protected static Boolean mEncrypt = Boolean.FALSE;
+
+ private boolean secureLogin = false;
+ private String loginHttpsPort = SslUtil.STD_HTTPS_PORT;
+
+ //=========================================================================
+ // Private Member Variables
+ //=========================================================================
+ private static Log mLogger = LogFactory.getLog(LoginServlet.class);
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * Validates the Init and Context parameters, configures authentication URL
+ *
+ * @throws ServletException if the init parameters are invalid or any
+ * other problems occur during initialisation
+ */
+ public void init() throws ServletException
+ {
+ // Get the container authentication URL for FORM-based Authentication
+ // J2EE spec says should be j_security_check
+ if (getInitParameter("authURL") != null)
+ {
+ mAuthURL = getInitParameter("authURL");
+ }
+
+ String secureLogin = RollerConfig.getProperty("securelogin.enabled");
+ if(secureLogin != null && "true".equalsIgnoreCase(secureLogin))
+ this.secureLogin = true;
+
+ String secureLoginPort = RollerConfig.getProperty("securelogin.https.port");
+ if(secureLoginPort != null)
+ this.loginHttpsPort = secureLoginPort;
+
+ mLogger.info("secure login enabled: "+this.secureLogin);
+ mLogger.info("secure login port: "+this.loginHttpsPort);
+ }
+
+ /**
+ * Route the user to the execute method
+ *
+ * @param request The HTTP request we are processing
+ * @param response The HTTP response we are creating
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception ServletException if a servlet exception occurs
+ */
+ public void doGet(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException
+ {
+ execute(request, response);
+ }
+
+ /**
+ * Route the user to the execute method
+ *
+ * @param request The HTTP request we are processing
+ * @param response The HTTP response we are creating
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception ServletException if a servlet exception occurs
+ */
+ public void doPost(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException
+ {
+ execute(request, response);
+ }
+
+ /**
+ * Process the specified HTTP request, and create the corresponding HTTP
+ * response (or forward to another web component that will create it).
+ *
+ * @param request The HTTP request we are processing
+ * @param response The HTTP response we are creating
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception ServletException if a servlet exception occurs
+ */
+ public void execute(HttpServletRequest request,
+ HttpServletResponse response) throws IOException,
+ ServletException
+ {
+ // if user is already authenticated, it means they probably bookmarked
+ // or typed in the URL to login.jsp directly, route them to the main
+ // menu if this is the case
+ if (request.getRemoteUser() != null) {
+ if (mLogger.isDebugEnabled()) {
+ mLogger.debug("User '" + request.getRemoteUser() +
+ "' already logged in, routing to main");
+ }
+ response.sendRedirect(request.getContextPath() + "/main.do");
+ return;
+ }
+
+ // Extract attributes we will need
+ String username = request.getParameter("j_username");
+ String password = request.getParameter("j_password");
+
+ String encryptedPassword = getEncryptedPassword(request, username, password);
+
+ String req = null;
+ String contextUrl = null;
+ if (this.secureLogin)
+ {
+ // Secure login and app server may not know it, so we must build URL
+ StringBuffer sb = new StringBuffer("");
+ sb.append("https://");
+ if (this.loginHttpsPort.equals(SslUtil.STD_HTTPS_PORT))
+ {
+ sb.append(request.getServerName());
+ }
+ else
+ {
+ sb.append(request.getServerName() + ":" + this.loginHttpsPort);
+ }
+ sb.append(request.getContextPath());
+ contextUrl = sb.toString();
+ }
+ else
+ {
+ contextUrl = request.getContextPath();
+ }
+ // TODO: is there a way we can do this without having password in the URL?
+ req = contextUrl + mAuthURL
+ + "?j_username=" + username
+ + "&j_password=" + encryptedPassword
+ + "&j_uri=" + request.getParameter("j_uri");
+
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("Authenticating user '" + username + "'");
+ }
+
+ response.sendRedirect(response.encodeRedirectURL(req));
+ }
+
+ /**
+ * Encode the user's password (if necessary) before redirecting to
+ * the Container Managed Security servlet.
+ *
+ * @param request
+ * @param username
+ * @param password
+ * @return
+ */
+ public static String getEncryptedPassword(
+ HttpServletRequest request, String username, String password)
+ {
+ // This determines if the password should be encrypted programmatically
+ mEncrypt = new Boolean(RollerConfig.getProperty("passwds.encryption.enabled"));
+ mAlgorithm = RollerConfig.getProperty("passwds.encryption.algorithm");
+
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("Authentication URL: " + mAuthURL);
+ mLogger.debug("Programmatic encryption of password? " + mEncrypt);
+ mLogger.debug("Encryption algorithm: " + mAlgorithm);
+ }
+
+ if (request.getParameter("rememberMe") != null) {
+ request.getSession().setAttribute(RollerRequest.LOGIN_COOKIE, "true");
+ }
+ String encryptedPassword = "";
+ if (mEncrypt.booleanValue() && (request.getAttribute("encrypt") == null))
+ {
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("Encrypting password for user '" + username + "'");
+ }
+ encryptedPassword = Utilities.encodePassword(password, mAlgorithm);
+ }
+ else
+ {
+ encryptedPassword = password;
+ }
+ return encryptedPassword;
+ }
+}
\ No newline at end of file
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/MainPageAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/MainPageAction.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/MainPageAction.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/MainPageAction.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,194 @@
+package org.roller.presentation;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.roller.RollerException;
+import org.roller.model.Roller;
+import org.roller.model.WeblogManager;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.roller.config.RollerRuntimeConfig;
+
+
+/**
+ * Main page action for Roller.
+ * @struts.action name="main" path="/main" scope="request"
+ * @struts.action-forward name="main.page" path="/main.jsp"
+ */
+public class MainPageAction extends Action
+{
+ // TODO: make timeouts configurable
+ private static TimedHolder mPopularWebsites = new TimedHolder(30 * 60 * 1000);
+ private static TimedHolder mRecentEntries = new TimedHolder(120 * 60 * 1000);
+ private static TimedHolder mPinnedEntries = new TimedHolder(120 * 60 * 1000);
+
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(MainPageAction.class);
+
+ /**
+ * Loads model and forwards to main.page.
+ */
+ public ActionForward execute(
+ ActionMapping mapping, ActionForm form,
+ HttpServletRequest req, HttpServletResponse res)
+ throws Exception
+ {
+ RollerContext rctx = RollerContext.getRollerContext(req);
+
+ req.setAttribute("version",rctx.getRollerVersion());
+ req.setAttribute("buildTime",rctx.getRollerBuildTime());
+ req.setAttribute("baseURL", rctx.getContextUrl(req));
+ req.setAttribute("data", new MainPageData(req));
+
+ /* I am pretty sure this value isn't used on the display anymore,
+ * but I am scared to remove it ... Allen G */
+ boolean allowNewUsers =
+ RollerRuntimeConfig.getBooleanProperty("users.registration.enabled");
+
+ java.security.Principal prince = req.getUserPrincipal();
+ if (prince != null)
+ {
+ req.setAttribute("loggedIn",Boolean.TRUE);
+ req.setAttribute("userName",prince.getName());
+ }
+ else if (allowNewUsers)
+ {
+ req.setAttribute("allowNewUsers",Boolean.TRUE);
+ }
+ req.setAttribute("leftPage","/theme/status.jsp");
+
+ return mapping.findForward("main.page");
+ }
+
+ public static void flushMainPageCache()
+ {
+ mLogger.debug("Flushing recent and pinned entries");
+ mRecentEntries.expire();
+ mPinnedEntries.expire();
+ }
+
+ /**
+ * Page model.
+ */
+ public static class MainPageData
+ {
+ private HttpServletRequest mRequest = null;
+
+ public MainPageData(HttpServletRequest req)
+ {
+ mRequest = req;
+ }
+
+ /**
+ * Get list of most popular websites in terms of day hits.
+ * @param num Number of entries to return (takes effect on next cache refresh)
+ */
+ public List getPopularWebsites(int num) throws RollerException
+ {
+ List list = (List)mPopularWebsites.getObject();
+ if (list == null)
+ {
+ mLogger.debug("Refreshing popular websites list");
+ Roller roller = RollerRequest.getRollerRequest(mRequest).getRoller();
+ list = roller.getRefererManager().getDaysPopularWebsites(num);
+ mPopularWebsites.setObject(list);
+ }
+ return list;
+ }
+
+ /**
+ * Get list of recent weblog entries.
+ * @param num Number of entries to return (takes effect on next cache refresh)
+ */
+ public List getRecentWeblogEntries(int num) throws RollerException
+ {
+ List list = (List)mRecentEntries.getObject();
+ try {
+ if (list == null)
+ {
+ mLogger.debug("Refreshing recent entries list");
+ Roller roller = RollerRequest.getRollerRequest(mRequest).getRoller();
+ list = roller.getWeblogManager().getWeblogEntries(
+ null, // userName
+ null, // startDate
+ new Date(), // endDate
+ null, // catName
+ WeblogManager.PUB_ONLY, // status
+ new Integer(num)); // maxEntries
+ mRecentEntries.setObject(list);
+ }
+ }
+ catch (Exception e)
+ {
+ mLogger.error(e);
+ }
+ return list;
+ }
+
+ /**
+ * Get list of recent weblog pinned entries
+ * @param num Number of entries to return (takes effect on next cache refresh)
+ */
+ public List getWeblogEntriesPinnedToMain(int num) throws RollerException
+ {
+ List list = (List)mPinnedEntries.getObject();
+ if (list == null)
+ {
+ mLogger.debug("Refreshing pinned entries list");
+ Roller roller = RollerRequest.getRollerRequest(mRequest).getRoller();
+ list = roller.getWeblogManager()
+ .getWeblogEntriesPinnedToMain(new Integer(num));
+ mPinnedEntries.setObject(list);
+ }
+ return list;
+ }
+ }
+
+ /** Hold object and expire after timeout passes. */
+ public static class TimedHolder
+ {
+ private Object obj = null;
+ private long updated = 0L;
+ private long timeout = 3000L; // 3 seconds ?? -Lance
+
+ /** Create holder with timeout */
+ public TimedHolder(long timeout)
+ {
+ this.timeout = timeout;
+ }
+ /** Set object and reset the timeout clock */
+ public synchronized void setObject(Object obj)
+ {
+ this.obj = obj;
+ this.updated = new Date().getTime();
+ }
+ /** Force object to expire */
+ public synchronized void expire()
+ {
+ this.obj = null;
+ }
+ /** Get object or null if object has expired */
+ public Object getObject()
+ {
+ long currentTime = new Date().getTime();
+ if ((currentTime - this.updated) > this.timeout)
+ {
+ return null;
+ }
+ else
+ {
+ return this.obj;
+ }
+ }
+ }
+}
+
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/ResourceServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/ResourceServlet.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/ResourceServlet.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/ResourceServlet.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,136 @@
+package org.roller.presentation;
+
+import java.io.*;
+import java.util.Date;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.roller.model.RollerFactory;
+
+
+/**
+ * Resources servlet. Acts as a gateway to files uploaded by users.
+ *
+ * Since we keep uploaded resources in a location outside of the webapp
+ * context we need a way to serve them up. This servlet assumes that
+ * resources are stored on a filesystem in the "uploads.dir" directory.
+ *
+ * @author Allen Gilliland
+ *
+ * @web.servlet name="ResourcesServlet"
+ * @web.servlet-mapping url-pattern="/resources/*"
+ */
+public class ResourceServlet extends HttpServlet
+{
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(ResourceServlet.class);
+
+ private String upload_dir = null;
+ private ServletContext context = null;
+
+
+ /** Initializes the servlet.*/
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+
+ this.context = config.getServletContext();
+
+ try {
+ this.upload_dir = RollerFactory.getRoller().getFileManager().getUploadDir();
+ mLogger.debug("upload dir is ["+this.upload_dir+"]");
+ } catch(Exception e) { mLogger.warn(e); }
+
+ }
+
+ /** Destroys the servlet.
+ */
+ public void destroy() {
+
+ }
+
+
+ /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
+ * @param request servlet request
+ * @param response servlet response
+ */
+ protected void processRequest(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+
+ String context = request.getContextPath();
+ String servlet = request.getServletPath();
+ String reqURI = request.getRequestURI();
+
+ // calculate the path of the requested resource
+ // we expect ... /<context>/<servlet>/path/to/resource
+ String reqResource = reqURI.substring(servlet.length() + context.length());
+
+ // now we can formulate the *real* path to the resource on the filesystem
+ String resource_path = this.upload_dir + reqResource;
+ File resource = new File(resource_path);
+
+ mLogger.debug("Resource requested ["+reqURI+"]");
+ mLogger.debug("Real path is ["+resource.getAbsolutePath()+"]");
+
+ // do a quick check to make sure the resource exits, otherwise 404
+ if(!resource.exists() || !resource.canRead()) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ // does the client already have this file? if so, then 304
+ Date ifModDate = new Date(request.getDateHeader("If-Modified-Since"));
+ Date lastMod = new Date(resource.lastModified());
+ if(lastMod.compareTo(ifModDate) <= 0) {
+ mLogger.debug("Resource unmodified ... sending 304");
+ response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+ return;
+ }
+
+ // looks like we'll be serving up the file ... lets set some headers
+ // set last-modified date so we can do if-modified-since checks
+ // set the content type based on whatever is in our web.xml mime defs
+ response.addDateHeader("Last-Modified", (new Date()).getTime());
+ response.setContentType(this.context.getMimeType(resource.getAbsolutePath()));
+
+ // ok, lets serve up the file
+ byte[] buf = new byte[8192];
+ int length = 0;
+ OutputStream out = response.getOutputStream();
+ InputStream resource_file = new FileInputStream(resource);
+ while((length = resource_file.read(buf)) > 0)
+ out.write(buf, 0, length);
+
+ // cleanup
+ out.close();
+ resource_file.close();
+ }
+
+
+ /** Handles the HTTP <code>GET</code> method.
+ * @param request servlet request
+ * @param response servlet response
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ processRequest(request, response);
+ }
+
+ /** Handles the HTTP <code>POST</code> method.
+ * @param request servlet request
+ * @param response servlet response
+ */
+ protected void doPost(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ processRequest(request, response);
+ }
+
+ /** Returns a short description of the servlet.
+ */
+ public String getServletInfo() {
+ return "ResourceServlet ... serving you since 2005 ;)";
+ }
+
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/RollerContext.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/RollerContext.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/RollerContext.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/RollerContext.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,644 @@
+package org.roller.presentation;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+import java.util.TimerTask;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSessionEvent;
+import javax.sql.DataSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.util.RequestUtils;
+import org.roller.RollerException;
+import org.roller.config.RollerConfig;
+import org.roller.model.RefererManager;
+import org.roller.model.Roller;
+import org.roller.model.RollerFactory;
+import org.roller.model.RollerSpellCheck;
+import org.roller.model.ScheduledTask;
+import org.roller.pojos.UserData;
+import org.roller.pojos.WeblogEntryData;
+import org.roller.presentation.velocity.CommentAuthenticator;
+import org.roller.presentation.velocity.ContextLoader;
+import org.roller.presentation.velocity.DefaultCommentAuthenticator;
+import org.roller.presentation.pings.PingQueueTask;
+import org.roller.util.StringUtils;
+import org.roller.util.Utilities;
+
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
+import org.roller.business.utils.UpgradeDatabase;
+import org.roller.config.RollerRuntimeConfig;
+import org.roller.config.PingConfig;
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ * Responds to app init/destroy events and holds Roller instance.
+ * @web.listener
+ */
+public class RollerContext implements ServletContextListener
+{
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(RollerContext.class);
+
+ private String mVersion = null;
+ private String mBuildTime = null;
+ private String mBuildUser = null;
+
+ public static final String ROLLER_KEY = "session.roller";
+ public static final String ROLLER_CONTEXT = "roller.context";
+ public static final String USER_RESOURCES = "/resources";
+ public static final String VERSION_KEY = "org.roller.version";
+ public static final String MEMDEBUG_KEY = "org.roller.memdebug";
+ public static final String INDEX_MGR_KEY = "org.roller.indexMgr";
+ public static final String HTTP_PORT = "http_port";
+ public static final String HTTPS_PORT = "https_port";
+ public static final String HTTPS_HEADER_NAME = "https_header_name";
+ public static final String HTTPS_HEADER_VALUE = "https_header_value";
+ private static final String HOURLY_TASK_KEY = "roller.hourly.tasks";
+ private static final String DAILY_TASK_KEY = "roller.daily.tasks";
+
+ private static final String ROLLER_IMPL_KEY
+ = "org.roller.persistence";
+
+ private static final String ROLLER_COMMENT_AUTH_KEY
+ = "org.roller.commentAuthenticatorClass";
+
+ private static ServletContext mContext = null;
+ private static Authenticator mAuthenticator = null;
+ private static CommentAuthenticator mCommentAuthenticator = null;
+ private final SynchronizedInt mSessionCount = new SynchronizedInt(0);
+ private boolean mMemDebug = false;
+
+ /**
+ * Constructor for RollerContext.
+ */
+ public RollerContext()
+ {
+ super();
+ Properties props = new Properties();
+ try
+ {
+ props.load(getClass().getResourceAsStream("/version.properties"));
+ }
+ catch (IOException e)
+ {
+ mLogger.error("version.properties not found", e);
+ }
+ mVersion = props.getProperty("ro.version", "UNKNOWN");
+ mBuildTime = props.getProperty("ro.buildTime", "UNKNOWN");
+ mBuildUser = props.getProperty("ro.buildUser", "UNKNOWN");
+ }
+
+ //-----------------------------------------------------------------------
+ /* Returns Roller instance for specified app */
+ public static RollerContext getRollerContext(ServletContext sc)
+ {
+ // get roller from servlet context
+ return (RollerContext) sc.getAttribute(ROLLER_CONTEXT);
+ }
+
+ //-----------------------------------------------------------------------
+ /* Returns Roller instance for specified app */
+ public static RollerContext getRollerContext(HttpServletRequest req)
+ {
+ // get roller from servlet context
+ ServletContext sc = RollerContext.getServletContext();
+ return (RollerContext) sc.getAttribute(ROLLER_CONTEXT);
+ }
+
+ //-----------------------------------------------------------------------
+ /** Responds to app-destroy by saving the indexManager's information */
+ public void contextDestroyed(ServletContextEvent sce)
+ {
+ RollerFactory.getRoller().shutdown();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Responds to context initialization event by processing context
+ * paramters for easy access by the rest of the application.
+ */
+ public void contextInitialized(ServletContextEvent sce)
+ {
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("RollerContext initializing");
+ }
+
+ // Save context in self and self in context
+ mContext = sce.getServletContext();
+ mContext.setAttribute(ROLLER_CONTEXT, this);
+
+ try
+ {
+ // get the *real* path to <context>/resources
+ String ctxPath = mContext.getRealPath("/");
+ if(!ctxPath.endsWith(File.separator))
+ ctxPath += File.separator + "resources";
+ else
+ ctxPath += "resources";
+
+ // try setting the uploads path to <context>/resources
+ // NOTE: this should go away at some point
+ // we leave it here for now to allow users to keep writing
+ // uploads into their webapp context, but this is a bad idea
+ //
+ // also, the RollerConfig.setUploadsDir() method is smart
+ // enough to disregard this call unless the uploads.path
+ // is set to ${webapp.context}
+ RollerConfig.setUploadsDir(ctxPath);
+
+ // set the roller context real path in RollerConfig
+ // NOTE: it seems that a few backend classes do actually need
+ // to know what the real path to the roller context is,
+ // so we set this property to give them the info they need.
+ //
+ // this is really not a best practice and we should try to
+ // remove these dependencies on the webapp context if possible
+ RollerConfig.setContextPath(mContext.getRealPath("/"));
+
+ // always upgrade database first
+ upgradeDatabaseIfNeeded();
+
+ Roller roller = RollerFactory.getRoller();
+ roller.begin(UserData.SYSTEM_USER);
+
+ setupRollerProperties();
+ roller.getThemeManager();
+ setupSpellChecker();
+ setupPagePlugins();
+ setupIndexManager(roller);
+ setupRefererManager(roller);
+ initializePingFeatures(roller);
+ setupPingQueueTask(roller);
+ setupScheduledTasks(mContext, roller);
+
+ roller.commit();
+ roller.release();
+
+ String flag = RollerConfig.getProperty("debug.memory.enabled");
+ if (flag != null && !flag.equalsIgnoreCase("false"))
+ {
+ mMemDebug = true;
+ }
+
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("RollerContext initialization complete");
+ }
+ }
+ catch (Throwable t)
+ {
+ mLogger.fatal("RollerContext initialization failed", t);
+ }
+ }
+
+
+ private void setupRollerProperties() throws RollerException
+ {
+ // init property manager by creating it
+ Roller mRoller = RollerFactory.getRoller();
+ mRoller.getPropertiesManager();
+ }
+
+ /** Setup daily and hourly tasks specified in web.xml */
+ private void setupScheduledTasks(ServletContext context, Roller roller)
+ throws RollerException, InstantiationException,
+ IllegalAccessException, ClassNotFoundException
+ {
+ // setup the hourly tasks
+ String hourlyString = RollerConfig.getProperty("tasks.hourly");
+ if (hourlyString != null && hourlyString.trim().length() > 0)
+ {
+ String[] hourlyTasks = StringUtils.stripAll(
+ StringUtils.split(hourlyString, ",") );
+ for (int i=0; i<hourlyTasks.length; i++)
+ {
+ mLogger.info("Setting hourly task: "+hourlyTasks[i]);
+ ScheduledTask task =
+ (ScheduledTask)Class.forName(hourlyTasks[i]).newInstance();
+ task.init(roller, mContext.getRealPath("/"));
+ roller.getThreadManager().scheduleHourlyTimerTask((TimerTask)task);
+ }
+ }
+
+ // setup the daily tasks
+ String dailyString = RollerConfig.getProperty("tasks.daily");
+ if (dailyString != null && dailyString.trim().length() > 0)
+ {
+ String[] dailyTasks = StringUtils.stripAll(
+ StringUtils.split(dailyString, ",") );
+ for (int j=0; j<dailyTasks.length; j++)
+ {
+ mLogger.info("Setting daily task: "+dailyTasks[j]);
+ ScheduledTask task =
+ (ScheduledTask)Class.forName(dailyTasks[j]).newInstance();
+ task.init(roller, mContext.getRealPath("/"));
+ roller.getThreadManager().scheduleDailyTimerTask((TimerTask)task);
+ }
+ }
+ }
+
+ // Initialize ping features
+ private void initializePingFeatures(Roller roller) throws RollerException {
+ // Initialize common targets from the configuration
+ PingConfig.initializeCommonTargets();
+ // Remove csutom ping targets if they have been disallowed
+ if (PingConfig.getDisallowCustomTargets()) {
+ mLogger.info("Custom ping targets have been disallowed. Removing any existing custom targets.");
+ roller.getPingTargetManager().removeAllCustomPingTargets();
+ }
+ // Remove all autoping configurations if ping usage has been disabled.
+ if (PingConfig.getDisablePingUsage()) {
+ mLogger.info("Ping usage has been disabled. Removing any existing auto ping configurations.");
+ roller.getAutopingManager().removeAllAutoPings();
+ }
+ }
+
+
+ // Set up the ping queue processing task
+ private void setupPingQueueTask(Roller roller) throws RollerException
+ {
+ long intervalMins = PingConfig.getQueueProcessingIntervalMins();
+ if (intervalMins == 0) {
+ // Ping queue processing interval of 0 indicates that ping queue processing is disabled on this host.
+ // This provides a crude way to disable running the ping queue task on some servers if there are
+ // multiple servers in a cluster sharing a db. Exclusion should really be handled dynamically but isn't.
+ mLogger.warn("Ping queue processing interval is zero; processing from the ping queue will be disabled on this server.");
+ mLogger.warn("Please make sure that ping queue processing is configured to run on one server in the cluster.");
+ return;
+ }
+
+ // Set up the task
+ PingQueueTask pingQueueTask = new PingQueueTask();
+ pingQueueTask.init(this, intervalMins);
+
+ // Schedule it at the appropriate interval, delay start for one interval.
+ mLogger.info("Scheduling ping queue task to run at " + intervalMins + " minute intervals.");
+ roller.getThreadManager().scheduleFixedRateTimerTask(pingQueueTask, intervalMins, intervalMins);
+ }
+
+ protected void upgradeDatabaseIfNeeded() throws RollerException
+ {
+ try
+ {
+ InitialContext ic = new InitialContext();
+ DataSource ds = (DataSource)ic.lookup("java:comp/env/jdbc/rollerdb");
+ Connection con = ds.getConnection();
+ UpgradeDatabase.upgradeDatabase(con, mVersion);
+ con.close();
+ }
+ catch (NamingException e)
+ {
+ mLogger.warn("Unable to access DataSource", e);
+ }
+ catch (SQLException e)
+ {
+ mLogger.warn(e);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ /**
+ * Initialize the configured PagePlugins
+ * @param mContext
+ */
+ private void setupPagePlugins()
+ {
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("Initialize PagePlugins");
+ }
+ ContextLoader.initializePagePlugins(mContext);
+
+ }
+
+ /**
+ * Add TurnoverReferersTask to run on a schedule.
+ */
+ private void setupRefererManager(Roller roller)
+ {
+ try
+ {
+ // Check for turnover when we first start
+ final RefererManager refManager = roller.getRefererManager();
+ refManager.checkForTurnover(false, null);
+
+ // Schedule a check every day, starting at end of today
+ //TurnoverReferersTask task = new TurnoverReferersTask();
+ //task.init(roller, mContext.getRealPath("/"));
+ //roller.getThreadManager().scheduleDailyTimerTask(task);
+ }
+ catch (RollerException e)
+ {
+ mLogger.warn("Couldn't schedule referer turnover task", e);
+ }
+ }
+
+ //------------------------------------------------------------------------
+
+ private void setupIndexManager(Roller roller) throws RollerException
+ {
+ roller.getIndexManager();
+ }
+
+ public void sessionCreated(HttpSessionEvent se)
+ {
+ if (mMemDebug)
+ {
+ mSessionCount.increment();
+ mContext.log(
+ "Roller:SESSION_CREATED:count="
+ + mSessionCount
+ + ":freemem="
+ + Runtime.getRuntime().freeMemory()
+ + ":totmem="
+ + Runtime.getRuntime().totalMemory());
+ }
+ }
+
+ //------------------------------------------------------------------------
+
+ public void sessionDestroyed(HttpSessionEvent se)
+ {
+ if (mMemDebug)
+ {
+ mSessionCount.decrement();
+ mContext.log(
+ "Roller:SESSION_DESTROY:count="
+ + mSessionCount
+ + ":freemem="
+ + Runtime.getRuntime().freeMemory()
+ + ":totalmem="
+ + Runtime.getRuntime().totalMemory());
+ }
+ }
+
+ //------------------------------------------------------------------------
+
+ /**
+ * Get an instance of Roller from the RollerFactory.
+ * If one does not exist, tell Factory to create new one.
+ */
+ public static Roller getRoller(HttpServletRequest req)
+ {
+ return RollerFactory.getRoller();
+ }
+
+ //------------------------------------------------------------------------
+
+ /**
+ * Get authenticator
+ */
+ public Authenticator getAuthenticator()
+ {
+ if (mAuthenticator == null)
+ {
+ try
+ {
+ Class authClass =
+ Class.forName(RollerConfig.getProperty("authenticator.classname"));
+ mAuthenticator = (Authenticator) authClass.newInstance();
+ }
+ catch (Exception e)
+ {
+ // this isn't an ERROR if no authenticatorClass was specified
+ if (!(e instanceof NullPointerException))
+ {
+ mLogger.error("ERROR creating authenticator, using default", e);
+ }
+ else
+ {
+ mLogger.debug("No authenticator specified, using DefaultAuthenticator");
+ }
+ mAuthenticator = new DefaultAuthenticator();
+ }
+ }
+ return mAuthenticator;
+ }
+
+
+ /**
+ * Gets the hard-drive location of the upload directory.
+ */
+ public static String getUploadDir(ServletContext app)
+ {
+ // ACK ... this really isn't the right place for this lookup!!
+ String uploaddir = null;
+ try
+ {
+ uploaddir = RollerFactory.getRoller().getFileManager().getUploadDir();
+ }
+ catch(Exception e) {}
+
+ return uploaddir;
+ }
+
+
+ /**
+ * Gets the base url for the upload directory.
+ */
+ public static String getUploadPath(ServletContext app)
+ {
+ // ACK ... why do this here??
+ String uploadurl = null;
+ try {
+ uploadurl = RollerFactory.getRoller().getFileManager().getUploadUrl();
+ } catch(Exception e) {}
+
+ return uploadurl;
+ }
+
+ /**
+ * RollerSpellCheck must be initialized with a dictionary file
+ * so that it can return valid a SpellChecker.
+ */
+ private void setupSpellChecker()
+ {
+ InputStream is = null;
+ try
+ {
+ is = mContext.getResourceAsStream("/WEB-INF/english.0");
+ RollerSpellCheck.init(is);
+ }
+ catch (Exception e)
+ {
+ mContext.log("ERROR reading dictionary file");
+ }
+ finally
+ {
+ if (is != null)
+ {
+ try
+ {
+ is.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Returns the full url for the website of the specified username.
+ */
+ public String getContextUrl(HttpServletRequest request, String username)
+ {
+ String url = this.getContextUrl(request);
+ if (username != null)
+ {
+ url = url + "/page/" + username;
+ }
+ return url;
+ }
+
+ //-----------------------------------------------------------------------
+ /** Get absolute URL of Roller context */
+ public String getContextUrl(HttpServletRequest request)
+ {
+ String url = request.getContextPath();
+ if (url.endsWith("/"))
+ {
+ url = url.substring(0, url.length() - 1);
+ }
+ return url;
+ }
+
+ //-----------------------------------------------------------------------
+ /** Get absolute URL of Roller context */
+ public String getAbsoluteContextUrl(HttpServletRequest request)
+ {
+ String url = RollerRuntimeConfig.getProperty("site.absoluteurl");
+
+ if (url == null || url.trim().length() == 0)
+ {
+ try
+ {
+ URL absURL = RequestUtils.absoluteURL(request, "/");
+ url = absURL.toString();
+ }
+ catch (MalformedURLException e)
+ {
+ url = "/";
+ mLogger.error("ERROR: forming absolute URL", e);
+ }
+ }
+ if (url.endsWith("/"))
+ {
+ url = url.substring(0, url.length() - 1);
+ }
+ mContext.setAttribute("org.roller.absoluteContextURL", url);
+ return url;
+ }
+
+ //-----------------------------------------------------------------------
+
+ /**
+ * For use by MetaWeblog API.
+ * @return Context URL or null if not initialized yet.
+ */
+ public String getAbsoluteContextUrl()
+ {
+ return (String) mContext.getAttribute("org.roller.absoluteContextURL");
+ }
+
+ //-----------------------------------------------------------------------
+
+ public String createEntryPermalink(
+ WeblogEntryData entry,
+ HttpServletRequest request,
+ boolean absolute)
+ {
+ String link = null;
+ try
+ {
+ String baseUrl = null;
+ if (absolute)
+ {
+ baseUrl = getAbsoluteContextUrl(request);
+ }
+ else
+ {
+ baseUrl = getContextUrl(request);
+ }
+
+ link = Utilities.escapeHTML(baseUrl + entry.getPermaLink());
+ }
+ catch (Exception e)
+ {
+ mLogger.error("Unexpected exception", e);
+ }
+
+ return link;
+ }
+
+
+ /**
+ * Returns the mContext.
+ * @return ServletContext
+ */
+ public static ServletContext getServletContext()
+ {
+ return mContext;
+ }
+
+
+ /** Roller version */
+ public String getRollerVersion()
+ {
+ return mVersion;
+ }
+
+ //-----------------------------------------------------------------------
+
+ /** Roller build time */
+ public String getRollerBuildTime()
+ {
+ return mBuildTime;
+ }
+
+ //-----------------------------------------------------------------------
+
+ /** Get username that built Roller */
+ public String getRollerBuildUser()
+ {
+ return mBuildUser;
+ }
+
+ //-----------------------------------------------------------------------
+
+ public static CommentAuthenticator getCommentAuthenticator()
+ {
+ if (mCommentAuthenticator == null)
+ {
+ String name = RollerConfig.getProperty("comment.authenticator.classname");
+ try
+ {
+ Class clazz = Class.forName(name);
+ mCommentAuthenticator=(CommentAuthenticator)clazz.newInstance();
+ }
+ catch (Exception e)
+ {
+ mLogger.error(e);
+ mCommentAuthenticator = new DefaultCommentAuthenticator();
+ }
+ }
+ return mCommentAuthenticator;
+ }
+}