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 [35/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/velocity/CommentServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/CommentServlet.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/CommentServlet.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/CommentServlet.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,573 @@
+package org.roller.presentation.velocity;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.naming.InitialContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.jsp.JspFactory;
+import javax.servlet.jsp.PageContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.util.RequestUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.context.Context;
+import org.roller.RollerException;
+import org.roller.config.RollerConfig;
+import org.roller.config.RollerRuntimeConfig;
+import org.roller.model.IndexManager;
+import org.roller.model.Roller;
+import org.roller.model.UserManager;
+import org.roller.model.WeblogManager;
+import org.roller.pojos.CommentData;
+import org.roller.pojos.WeblogTemplate;
+import org.roller.pojos.UserData;
+import org.roller.pojos.WeblogEntryData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.LanguageUtil;
+import org.roller.presentation.RollerContext;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.RollerSession;
+import org.roller.presentation.pagecache.PageCacheFilter;
+import org.roller.presentation.weblog.formbeans.CommentFormEx;
+import org.roller.util.CommentSpamChecker;
+import org.roller.util.MailUtil;
+import org.roller.util.StringUtils;
+
+/**
+ * Extend PageServlet to do special handling needed to support viewing and
+ * posting of comments. Handles in-page comments and popup-style comments.
+ * <p />
+ * This servlet overrides the VelocityServlet's handleRequest method so that
+ * the correct comments page template can be loaded for popup comments.
+ * If this servlet is called with the request paramteter 'popup'
+ * defined, then it will load the user's _popupcomments page and if no such
+ * page is found it will use /popupcomments.vm which looks just like the old
+ * pre-0.9.9 popup comments page.
+ * <p />
+ * This servlet also overrides doPost() to handle review and posting of new
+ * comments. If the request paramter 'method' is set to 'preview' then the
+ * posted comment will be previewed, otherwise if it will be posted.
+ * <p />
+ * Incoming comments are tested against the MT Blacklist. If they are found
+ * to be spam, then they are marked as spam and hidden from view.
+ * <p />
+ * If email notification is turned on, each new comment will result in an
+ * email sent to the blog owner and all who have commented on the same post.
+ *
+ * @web.servlet name="CommentServlet"
+ * @web.servlet-mapping url-pattern="/comments/*"
+ * @web.servlet-init-param name="org.apache.velocity.properties"
+ * value="/WEB-INF/velocity.properties"
+ *
+ * @author Dave Johnson
+ */
+public class CommentServlet extends PageServlet
+{
+ private static final String COMMENT_SPAM_MSG =
+ "Your comment has been recognized as "
+ + "<a href='http://www.jayallen.org/projects/mt-blacklist/'>"
+ + "Comment Spam</a> and rejected.";
+ private transient ResourceBundle bundle =
+ ResourceBundle.getBundle("ApplicationResources");
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(CommentServlet.class);
+
+ //-----------------------------------------------------------------------
+ /**
+ * Override VelocityServlet so we can pick the right page and stick
+ * the right stuff into the VelocityContext before page execution.
+ */
+ public Template handleRequest( HttpServletRequest request,
+ HttpServletResponse response,
+ Context ctx ) throws Exception
+ {
+ Template template = null;
+ if (request.getParameter("popup") == null)
+ {
+ // Request does not specify popup, so normal return
+ template = super.handleRequest(request, response, ctx);
+ }
+ else
+ {
+ PageContext pageContext =
+ JspFactory.getDefaultFactory().getPageContext(
+ this, request, response,"", true, 8192, true);
+ RollerRequest rreq= RollerRequest.getRollerRequest(pageContext);
+ UserManager userMgr = rreq.getRoller().getUserManager();
+ WebsiteData website = rreq.getWebsite();
+
+ // Request specifies popup
+ org.roller.pojos.Template page = null;
+ Exception pageException = null;
+ try
+ {
+ // Does user have a popupcomments page?
+ page = website.getPageByName("_popupcomments");
+ }
+ catch(Exception e )
+ {
+ pageException = e;
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ if (pageException != null)
+ {
+ mLogger.error("EXCEPTION: in RollerServlet", pageException);
+ request.setAttribute("DisplayException", pageException);
+ }
+ // User doesn't have one so return the default
+ if (page == null)
+ {
+ page = new WeblogTemplate("/popupcomments.vm", website, "Comments",
+ "Comments", "dummy_link", "dummy_template", new Date());
+ }
+ rreq.setPage(page);
+ template = prepareForPageExecution(ctx, rreq, response, page);
+ }
+ return template;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Handle POST from comment form, then hand off to super for page rendering.
+ */
+ public void doPost(
+ HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException
+ {
+ if (request.getParameter("method") != null
+ && request.getParameter("method").equals("preview"))
+ {
+ doPreviewPost(request, response);
+ return;
+ }
+
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ HttpSession session = request.getSession();
+ try
+ {
+ // Get weblog entry object, put in page context
+ WeblogEntryData wd = rreq.getWeblogEntry();
+ if (wd == null || wd.getId() == null)
+ {
+ throw new RollerException(
+ "Unable to find WeblogEntry for "
+ + request.getParameter(RollerRequest.WEBLOGENTRYID_KEY));
+ }
+ if ( !wd.getWebsite().getAllowComments().booleanValue()
+ || !wd.getCommentsStillAllowed())
+ {
+ throw new RollerException("ERROR comments not allowed");
+ }
+
+ request.setAttribute("blogEntry", wd);
+
+ // get the User to which the blog belongs
+ UserData user = wd.getWebsite().getUser();
+
+ // TODO: A hack to be replaced by Object.canEdit()
+ request.setAttribute(RollerRequest.OWNING_USER, user);
+
+ // Save comment
+ WeblogManager mgr = rreq.getRoller().getWeblogManager();
+ CommentFormEx cf = new CommentFormEx();
+ CommentData cd = new CommentData();
+ RequestUtils.populate(cf, request);
+ cf.copyTo(cd, request.getLocale());
+ cd.setWeblogEntry(wd);
+ cd.setRemoteHost(request.getRemoteHost());
+ cd.setPostTime(new java.sql.Timestamp(System.currentTimeMillis()));
+
+ if (!testCommentSpam(cd, request))
+ {
+ if (RollerContext.getCommentAuthenticator().authenticate(cd, request))
+ {
+ cd.save();
+ rreq.getRoller().commit();
+ reindexEntry(rreq.getRoller(), wd);
+
+ // Refresh user's entries in page cache
+ PageCacheFilter.removeFromCache(request, user);
+
+ // Put array of comments in context
+ List comments = mgr.getComments(wd.getId());
+ request.setAttribute("blogComments", comments);
+
+ // MR: Added functionality to e-mail comments
+ sendEmailNotification(request, rreq, wd, cd, user,comments);
+
+ super.doPost(request, response);
+ return;
+ }
+ else
+ {
+ request.getSession().setAttribute(
+ RollerSession.ERROR_MESSAGE,
+ bundle.getString("error.commentAuthFailed"));
+ }
+ }
+ doPreviewPost(request, response);
+ }
+ catch (Exception e)
+ {
+ mLogger.error("ERROR posting comment", e);
+ // Noted: this never gets back to the user. Not sure why it is being set.
+ session.setAttribute(RollerSession.ERROR_MESSAGE, e.getMessage());
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Load comment and blog entry objects and forward to either the popup
+ * or the in-page comment page for comment preview.
+ */
+ public void doPreviewPost(
+ HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException
+ {
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ try
+ {
+ WeblogEntryData wd = rreq.getWeblogEntry();
+ if (wd == null || wd.getId() == null)
+ {
+ throw new RollerException(
+ "Unable to find WeblogEntry for "
+ + request.getParameter(RollerRequest.WEBLOGENTRYID_KEY));
+ }
+ request.setAttribute("blogEntry", wd);
+
+ // TODO: A hack to be replaced by Object.canEdit()
+ request.setAttribute(RollerRequest.OWNING_USER, wd.getWebsite().getUser());
+
+ CommentFormEx cf = new CommentFormEx();
+ RequestUtils.populate(cf, request);
+ cf.setWeblogEntry(wd);
+ cf.setPostTime(new java.sql.Timestamp(System.currentTimeMillis()));
+ request.setAttribute("commentForm", cf);
+ request.setAttribute("previewComments","dummy");
+ }
+ catch (Exception e)
+ {
+ // TODO: error message for browser and log
+ mLogger.error(e);
+ }
+ super.doPost(request, response);
+ }
+
+ /**
+ * Re-index the WeblogEntry so that the new comment gets indexed.
+ * @param entry
+ */
+ private void reindexEntry(Roller roller, WeblogEntryData entry) throws RollerException
+ {
+ IndexManager manager = roller.getIndexManager();
+
+ // remove entry before (re)adding it, or in case it isn't Published
+ manager.removeEntryIndexOperation(entry);
+
+ // if published, index the entry
+ if (entry.getPublishEntry() == Boolean.TRUE)
+ {
+ manager.addEntryIndexOperation(entry);
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Test CommentData to see if it is spam, if it is set it's spam property
+ * to true and put a RollerSession.ERROR_MESSAGE message in the session.
+ * @param cd CommentData to be tested.
+ */
+ private boolean testCommentSpam(CommentData cd, HttpServletRequest req)
+ {
+ boolean ret = false;
+ CommentSpamChecker checker = new CommentSpamChecker();
+ checker.testComment(cd);
+ if (cd.getSpam().booleanValue())
+ {
+ HttpSession session = req.getSession();
+ session.setAttribute(
+ RollerSession.ERROR_MESSAGE, COMMENT_SPAM_MSG);
+ ret = true;
+ }
+ return ret;
+ }
+
+ //-----------------------------------------------------------------------
+
+ // Email notification
+
+ // agangolli: Incorporated suggested changes from Ken Blackler, with server-wide configurable options
+ // TODO: Make the addressing options configurable on a per-website basis.
+
+ private static final String EMAIL_ADDR_REGEXP = "^.*@.*[.].{2,}$";
+
+ // Servlet init params that control how messages are addressed server-wide. These default to false for old behavior
+ // Controls whether the owner and commenters get separate messages (owner's message contains a link to the entry edit page).
+ private static final String SEPARATE_OWNER_MSG_PARAM = CommentServlet.class.getName() + ".separateOwnerMessage";
+ // Controls whether the commenters addresses are placed in a Bcc header or a visible address field
+ private static final String HIDE_COMMENTER_ADDRESSES_PARAM = CommentServlet.class.getName() + ".hideCommenterAddresses";
+
+
+ /**
+ * Send email notification of comment.
+ */
+ private void sendEmailNotification(
+ HttpServletRequest request,
+ RollerRequest rreq,
+ WeblogEntryData wd,
+ CommentData cd,
+ UserData user,
+ List comments) throws MalformedURLException
+ {
+ RollerContext rc = RollerContext.getRollerContext(request);
+ ResourceBundle resources = ResourceBundle.getBundle(
+ "ApplicationResources",LanguageUtil.getViewLocale(request));
+ UserManager userMgr = null;
+ WebsiteData site = null;
+ try
+ {
+ userMgr = RollerContext.getRoller(request).getUserManager();
+ site = userMgr.getWebsite(user.getUserName());
+ }
+ catch (RollerException re)
+ {
+ re.printStackTrace();
+ mLogger.error(
+ "Couldn't get UserManager from RollerContext", re.getRootCause());
+ }
+
+ // Send e-mail to owner and subscribed users (if enabled)
+ boolean notify = RollerRuntimeConfig.getBooleanProperty("users.comments.emailnotify");
+ if (notify && site.getEmailComments().booleanValue())
+ {
+ mLogger.debug("Comment notification enabled ... preparing email");
+
+ // Determine message and addressing options from init parameters
+ boolean separateMessages =
+ RollerConfig.getBooleanProperty("comment.notification.separateOwnerMessage");
+ boolean hideCommenterAddrs =
+ RollerConfig.getBooleanProperty("comment.notification.hideCommenterAddresses");
+
+ //------------------------------------------
+ // --- Determine the "from" address
+ // --- Use either the site configured from address or the user's address
+
+ String from =
+ (StringUtils.isEmpty(site.getEmailFromAddress()))
+ ? user.getEmailAddress()
+ : site.getEmailFromAddress();
+
+ //------------------------------------------
+ // --- Build list of email addresses to send notification to
+
+ // Get all the subscribers to this comment thread
+ Set subscribers = new TreeSet();
+ for (Iterator it = comments.iterator(); it.hasNext();)
+ {
+ CommentData comment = (CommentData) it.next();
+ if (!StringUtils.isEmpty(comment.getEmail()))
+ {
+ // If user has commented twice,
+ // count the most recent notify setting
+ if (comment.getNotify().booleanValue())
+ {
+ // only add those with valid email
+ if (comment.getEmail().matches(EMAIL_ADDR_REGEXP))
+ {
+ subscribers.add(comment.getEmail());
+ }
+ }
+ else
+ {
+ // remove user who doesn't want to be notified
+ subscribers.remove(comment.getEmail());
+ }
+ }
+ }
+
+ // Form array of commenter addrs
+ String[] commenterAddrs = (String[])subscribers.toArray(new String[0]);
+
+ //------------------------------------------
+ // --- Form the messages to be sent -
+ // For simplicity we always build separate owner and commenter messages even if sending a single one
+
+ // Determine with mime type to use for e-mail
+ StringBuffer msg = new StringBuffer();
+ StringBuffer ownermsg = new StringBuffer();
+ boolean escapeHtml = RollerRuntimeConfig.getBooleanProperty("users.comments.escapehtml");
+
+ if (!escapeHtml)
+ {
+ msg.append("<html><body style=\"background: white; ");
+ msg.append(" color: black; font-size: 12px\">");
+ }
+
+ if (!StringUtils.isEmpty(cd.getName()))
+ {
+ msg.append(cd.getName() + " "
+ + resources.getString("email.comment.wrote")+": ");
+ }
+ else
+ {
+ msg.append(resources.getString("email.comment.anonymous")+": ");
+ }
+
+ msg.append((escapeHtml) ? "\n\n" : "<br /><br />");
+ msg.append(cd.getContent());
+ msg.append((escapeHtml) ? "\n\n----\n"
+ : "<br /><br /><hr /><span style=\"font-size: 11px\">");
+ msg.append(resources.getString("email.comment.respond") + ": ");
+ msg.append((escapeHtml) ? "\n" : "<br />");
+
+ String rootURL = rc.getAbsoluteContextUrl(request);
+ if (rootURL == null || rootURL.trim().length()==0)
+ {
+ rootURL = RequestUtils.serverURL(request) + request.getContextPath();
+ }
+
+ // Build link back to comment
+
+ StringBuffer commentURL = new StringBuffer(rootURL);
+ commentURL.append("/comments/");
+ commentURL.append(rreq.getUser().getUserName());
+
+ org.roller.pojos.Template page = rreq.getPage();
+ if (page == null)
+ {
+ commentURL.append("?entry=");
+ }
+ else
+ {
+ commentURL.append("/").append(page.getLink()).append("/");
+ }
+
+ commentURL.append(wd.getAnchor());
+
+ if (escapeHtml)
+ {
+ msg.append(commentURL.toString());
+ }
+ else
+ {
+ msg.append("<a href=\""+commentURL+"\">"+commentURL+"</a></span>");
+ }
+
+ ownermsg.append(msg);
+
+ // add link to weblog edit page so user can login to manage comments
+ ownermsg.append((escapeHtml) ? "\n\n----\n" :
+ "<br /><br /><hr /><span style=\"font-size: 11px\">");
+ ownermsg.append("Link to comment management page:");
+ ownermsg.append((escapeHtml) ? "\n" : "<br />");
+
+ StringBuffer deleteURL = new StringBuffer(rootURL);
+ deleteURL.append("/editor/weblog.do?method=edit&entryid="+wd.getId());
+
+ if (escapeHtml)
+ {
+ ownermsg.append(deleteURL.toString());
+ }
+ else
+ {
+ ownermsg.append(
+ "<a href=\"" + deleteURL + "\">" + deleteURL + "</a></span>");
+ msg.append("</Body></html>");
+ ownermsg.append("</Body></html>");
+ }
+
+ String subject = null;
+ if ((subscribers.size() > 1) ||
+ (StringUtils.equals(cd.getEmail(), user.getEmailAddress())))
+ {
+ subject= "RE: "+resources.getString("email.comment.title")+": ";
+ }
+ else
+ {
+ subject = resources.getString("email.comment.title") + ": ";
+ }
+ subject += wd.getTitle();
+
+ //------------------------------------------
+ // --- Send message to email recipients
+ try
+ {
+ javax.naming.Context ctx = (javax.naming.Context)
+ new InitialContext().lookup("java:comp/env");
+ Session session = (Session)ctx.lookup("mail/Session");
+ boolean isHtml = !escapeHtml;
+ if (separateMessages)
+ {
+ // Send separate messages to owner and commenters
+ sendMessage(session, from,
+ new String[]{user.getEmailAddress()}, null, null, subject, ownermsg.toString(), isHtml);
+ if (commenterAddrs.length > 0)
+ {
+ // If hiding commenter addrs, they go in Bcc: otherwise in the To: of the second message
+ String[] to = hideCommenterAddrs ? null : commenterAddrs;
+ String[] bcc = hideCommenterAddrs ? commenterAddrs : null;
+ sendMessage(session, from, to, null, bcc, subject, msg.toString(), isHtml);
+
+ }
+ }
+ else
+ {
+ // Single message. User in To: header, commenters in either cc or bcc depending on hiding option
+ String[] cc = hideCommenterAddrs ? null : commenterAddrs;
+ String[] bcc = hideCommenterAddrs ? commenterAddrs : null;
+ sendMessage(session, from, new String[]{user.getEmailAddress()}, cc, bcc, subject,
+ ownermsg.toString(), isHtml);
+ }
+ }
+ catch (javax.naming.NamingException ne)
+ {
+ mLogger.error("Unable to lookup mail session. Check configuration. NamingException: " + ne.getMessage());
+ }
+ catch (Exception e)
+ {
+ mLogger.warn("Exception sending comment mail: " + e.getMessage());
+ // This will log the stack trace if debug is enabled
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug(e);
+ }
+ }
+
+ mLogger.debug("Done sending email message");
+
+ } // if email enabled
+ }
+
+ // This is somewhat ridiculous, but avoids duplicating a bunch of logic in the already messy sendEmailNotification
+ private void sendMessage(Session session, String from, String[] to, String[] cc, String[] bcc, String subject,
+ String msg, boolean isHtml) throws MessagingException
+ {
+ if (isHtml)
+ MailUtil.sendHTMLMessage(session, from, to, cc, bcc, subject, msg);
+ else
+ MailUtil.sendTextMessage(session, from, to, cc, bcc, subject, msg);
+ }
+
+ /* old method not used anymore -- Allen G
+ private boolean getBooleanContextParam(String paramName, boolean defaultValue) {
+ String paramValue = getServletContext().getInitParameter(paramName);
+ if (paramValue == null) return defaultValue;
+ return Boolean.valueOf(paramValue).booleanValue();
+ }
+ */
+}
+
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/ContextLoader.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/ContextLoader.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/ContextLoader.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/ContextLoader.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,603 @@
+package org.roller.presentation.velocity;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.util.RequestUtils;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.tools.view.context.ChainedContext;
+import org.apache.velocity.tools.view.context.ToolboxContext;
+import org.apache.velocity.tools.view.servlet.ServletToolboxManager;
+import org.roller.RollerException;
+import org.roller.config.RollerConfig;
+import org.roller.config.RollerRuntimeConfig;
+import org.roller.model.Roller;
+import org.roller.model.RollerFactory;
+import org.roller.pojos.Template;
+import org.roller.pojos.CommentData;
+import org.roller.pojos.RollerPropertyData;
+import org.roller.pojos.UserData;
+import org.roller.pojos.WeblogEntryData;
+import org.roller.pojos.WebsiteData;
+import org.roller.pojos.wrapper.CommentDataWrapper;
+import org.roller.pojos.wrapper.TemplateWrapper;
+import org.roller.pojos.wrapper.WeblogEntryDataWrapper;
+import org.roller.pojos.wrapper.WebsiteDataWrapper;
+import org.roller.presentation.LanguageUtil;
+import org.roller.presentation.RollerContext;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.RollerSession;
+import org.roller.presentation.newsfeeds.NewsfeedCache;
+import org.roller.presentation.weblog.formbeans.CommentFormEx;
+import org.roller.util.RegexUtil;
+import org.roller.util.StringUtils;
+import org.roller.util.Utilities;
+
+/**
+ * Load Velocity Context with Roller objects, values, and custom plugins.
+ *
+ * @author llavandowska
+ * @author David M Johnson
+ */
+public class ContextLoader
+{
+ private RollerRequest mRollerReq = null;
+
+ // List of PagePlugins for "transforming" WeblogEntries
+ static List mPagePlugins = new ArrayList();
+
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(ContextLoader.class);
+
+ //------------------------------------------------------------------------
+
+ /**
+ * Setup the a Velocity context by loading it with objects, values, and
+ * RollerPagePlugins needed for Roller page execution.
+ */
+ public static void setupContext( Context ctx,
+ RollerRequest rreq, HttpServletResponse response )
+ throws RollerException
+ {
+ mLogger.debug("setupContext( ctx = "+ctx+")");
+
+ HttpServletRequest request = rreq.getRequest();
+ RollerContext rollerCtx = RollerContext.getRollerContext( request );
+
+ try
+ {
+ // Add page model object to context
+ String pageModelClassName =
+ RollerConfig.getProperty("velocity.pagemodel.classname");
+ Class pageModelClass = Class.forName(pageModelClassName);
+ PageModel pageModel = (PageModel)pageModelClass.newInstance();
+ pageModel.init(rreq);
+ ctx.put("pageModel", pageModel );
+ ctx.put("pages", pageModel.getPages());
+ }
+ catch (Exception e)
+ {
+ throw new RollerException("ERROR creating Page Model",e);
+ }
+
+ // Add Velocity page helper to context
+ PageHelper pageHelper = new PageHelper(rreq, response, ctx);
+ pageHelper.initializePlugins(mPagePlugins);
+ ctx.put("pageHelper", pageHelper );
+
+ // Add legacy macros too, so that old-school pages still work
+ Macros macros= new Macros(rreq.getPageContext(), pageHelper);
+ ctx.put("macros", macros);
+
+ // Load standard Roller objects and values into the context
+ String userName = loadWebsiteValues(ctx, rreq, rollerCtx );
+ loadWeblogValues( ctx, rreq, rollerCtx, userName );
+ loadPathValues( ctx, rreq, rollerCtx, userName );
+ loadRssValues( ctx, rreq, userName );
+ loadUtilityObjects( ctx, rreq, rollerCtx, userName );
+ loadRequestParamKeys(ctx);
+ loadStatusMessage( ctx, rreq );
+
+ // If single entry is specified, load comments too
+ if ( rreq.getWeblogEntry() != null )
+ {
+ loadCommentValues( ctx, rreq, rollerCtx );
+ }
+
+ // add Velocity Toolbox tools to context
+ loadToolboxContext(request, response, ctx);
+ }
+
+ //------------------------------------------------------------------------
+
+ /**
+ * If there is an ERROR or STATUS message in the session,
+ * place it into the Context for rendering later.
+ *
+ * @param rreq
+ */
+ private static void loadStatusMessage(Context ctx, RollerRequest rreq)
+ {
+ mLogger.debug("Loading status message");
+
+ HttpSession session = rreq.getRequest().getSession(false);
+ String msg = null;
+ if (session != null)
+ msg = (String)session.getAttribute(RollerSession.ERROR_MESSAGE);
+ if (msg != null)
+ {
+ ctx.put("errorMessage", msg);
+ session.removeAttribute(RollerSession.ERROR_MESSAGE);
+ }
+
+ if (session != null)
+ msg = (String)session.getAttribute(RollerSession.STATUS_MESSAGE);
+ if (msg != null)
+ {
+ ctx.put("statusMessage", msg);
+ session.removeAttribute(RollerSession.STATUS_MESSAGE);
+ }
+ }
+
+ //------------------------------------------------------------------------
+
+ /**
+ * @param ctx
+ * @param rreq
+ * @param rollerCtx
+ * @param userName
+ */
+ private static void loadWeblogValues(
+ Context ctx, RollerRequest rreq, RollerContext rollerCtx, String userName)
+ throws RollerException
+ {
+ mLogger.debug("Loading weblog values");
+
+ // if there is an "_entry" page, only load it once
+ WebsiteData website = RollerFactory.getRoller().getUserManager().getWebsite(userName);
+ //PageModel pageModel = (PageModel)ctx.get("pageModel");
+ if (website != null)
+ {
+ /* alternative display pages - customization */
+ Template entryPage = website.getPageByName("_entry");
+ if (entryPage != null)
+ {
+ ctx.put("entryPage", TemplateWrapper.wrap(entryPage));
+ }
+ Template descPage = website.getPageByName("_desc");
+ if (descPage != null)
+ {
+ ctx.put("descPage", TemplateWrapper.wrap(descPage));
+ }
+ }
+ }
+
+ private static String figureResourcePath( RollerRequest rreq )
+ {
+ String uploadurl = null;
+ try {
+ uploadurl = RollerFactory.getRoller().getFileManager().getUploadUrl();
+ } catch(Exception e) {}
+
+ return uploadurl;
+ }
+
+ //------------------------------------------------------------------------
+
+ public boolean isUserAuthorizedToEdit()
+ {
+ try
+ {
+ return mRollerReq.isUserAuthorizedToEdit();
+ }
+ catch (Exception e)
+ {
+ mLogger.warn("PageHelper.isUserAuthorizedToEdit)", e);
+ }
+ return false;
+ }
+
+ //------------------------------------------------------------------------
+
+ protected static void loadCommentValues(
+ Context ctx, RollerRequest rreq, RollerContext rollerCtx )
+ throws RollerException
+ {
+ mLogger.debug("Loading comment values");
+
+ HttpServletRequest request = rreq.getRequest();
+
+ String escapeHtml = RollerRuntimeConfig.getProperty("users.comments.escapehtml");
+ String autoFormat = RollerRuntimeConfig.getProperty("users.comments.autoformat");
+
+ // Add comments related values to context
+ ctx.put("isCommentPage", Boolean.TRUE);
+ ctx.put("escapeHtml", new Boolean(escapeHtml) );
+ ctx.put("autoformat", new Boolean(autoFormat) );
+
+ // Make sure comment form object is available in context
+ CommentFormEx commentForm =
+ (CommentFormEx) request.getAttribute("commentForm");
+ if ( commentForm == null )
+ {
+ commentForm = new CommentFormEx();
+
+ // Set fields to spaces to please Velocity
+ commentForm.setName("");
+ commentForm.setEmail("");
+ commentForm.setUrl("");
+ commentForm.setContent("");
+ }
+ ctx.put("commentForm",commentForm);
+
+ // Either put a preview comment in to context
+ if ( request.getAttribute("previewComments")!=null )
+ {
+ ArrayList list = new ArrayList();
+ CommentData cd = new CommentData();
+ commentForm.copyTo(cd, request.getLocale());
+ list.add(CommentDataWrapper.wrap(cd));
+ ctx.put("previewComments",list);
+ }
+ WeblogEntryData entry = rreq.getWeblogEntry();
+ ctx.put("entry", WeblogEntryDataWrapper.wrap(entry));
+ }
+
+ //------------------------------------------------------------------------
+
+ protected static void loadPathValues(
+ Context ctx, RollerRequest rreq, RollerContext rollerCtx, String userName)
+ throws RollerException
+ {
+ mLogger.debug("Loading path values");
+
+ HttpServletRequest request = rreq.getRequest();
+ String url = null;
+ if ( userName != null && !userName.equals("zzz_none_zzz"))
+ {
+ url = Utilities.escapeHTML(
+ rollerCtx.getAbsoluteContextUrl(request)+"/page/"+userName);
+ }
+ else
+ {
+ url= Utilities.escapeHTML(rollerCtx.getAbsoluteContextUrl(request));
+ }
+ ctx.put("websiteURL", url);
+ ctx.put("baseURL", rollerCtx.getContextUrl( request ) );
+ ctx.put("absBaseURL", rollerCtx.getAbsoluteContextUrl( request ) );
+ ctx.put("ctxPath", request.getContextPath() );
+ ctx.put("uploadPath", ContextLoader.figureResourcePath( rreq ) );
+
+ try
+ {
+ URL absUrl = RequestUtils.absoluteURL(request, "/");
+ ctx.put("host", absUrl.getHost());
+ }
+ catch (MalformedURLException e)
+ {
+ throw new RollerException(e);
+ }
+ }
+
+ //------------------------------------------------------------------------
+
+ protected static void loadRequestParamKeys(Context ctx)
+ {
+ mLogger.debug("Loading request param keys");
+
+ // Since Velocity *requires* accessor methods, these values from
+ // RollerRequest are not available to it, put them into the context
+ ctx.put("USERNAME_KEY", RollerRequest.USERNAME_KEY);
+ ctx.put("WEBSITEID_KEY", RollerRequest.WEBSITEID_KEY);
+ ctx.put("FOLDERID_KEY", RollerRequest.FOLDERID_KEY);
+ ctx.put("NEWSFEEDID_KEY", RollerRequest.NEWSFEEDID_KEY);
+ ctx.put("PAGEID_KEY", RollerRequest.PAGEID_KEY);
+ ctx.put("PAGELINK_KEY", RollerRequest.PAGELINK_KEY);
+ ctx.put("ANCHOR_KEY", RollerRequest.ANCHOR_KEY);
+ ctx.put("EXCERPTS_KEY", RollerRequest.EXCERPTS_KEY);
+ ctx.put("BOOKMARKID_KEY", RollerRequest.BOOKMARKID_KEY);
+ ctx.put("REFERERID_KEY", RollerRequest.REFERERID_KEY);
+ ctx.put("WEBLOGENTRYID_KEY", RollerRequest.WEBLOGENTRYID_KEY);
+ ctx.put("WEBLOGCATEGORYNAME_KEY", RollerRequest.WEBLOGCATEGORYNAME_KEY);
+ ctx.put("WEBLOGCATEGORYID_KEY", RollerRequest.WEBLOGENTRIES_KEY);
+ ctx.put("WEBLOGENTRIES_KEY", RollerRequest.WEBLOGENTRIES_KEY);
+ ctx.put("WEBLOGDAY_KEY", RollerRequest.WEBLOGDAY_KEY);
+ ctx.put("WEBLOGCOMMENTID_KEY", RollerRequest.WEBLOGCOMMENTID_KEY);
+ }
+
+ //------------------------------------------------------------------------
+
+ protected static void loadRssValues(
+ Context ctx, RollerRequest rreq, String userName) throws RollerException
+ {
+ mLogger.debug("Loading rss values");
+
+ HttpServletRequest request = rreq.getRequest();
+
+ int entryLength = -1;
+ String sExcerpts = request.getParameter("excerpts");
+ if ( sExcerpts!=null && sExcerpts.equalsIgnoreCase("true"))
+ {
+ entryLength = 150;
+ }
+ ctx.put("entryLength", new Integer(entryLength));
+
+ int entryCount = 15;
+ String sCount = request.getParameter("count");
+ if ( sCount!=null && sExcerpts.trim().equals(""))
+ {
+ try
+ {
+ entryCount = Integer.parseInt(sCount);
+ }
+ catch (NumberFormatException e)
+ {
+ mLogger.warn("Improperly formatted count parameter");
+ }
+ if ( entryCount > 50 ) entryCount = 50;
+ if ( entryCount < 0 ) entryCount = 15;
+ }
+ ctx.put("entryCount", new Integer(entryCount));
+
+ String catname = null;
+ String catPath = null;
+ if ( rreq.getWeblogCategory() != null )
+ {
+ catname = rreq.getWeblogCategory().getName();
+ catPath = rreq.getWeblogCategory().getPath();
+ }
+ ctx.put("catname", (catname!=null) ? catname : "");
+ ctx.put("catPath", (catPath != null) ? catPath : "");
+ ctx.put("updateTime", request.getAttribute("updateTime"));
+ ctx.put("now", new Date());
+ }
+
+ //------------------------------------------------------------------------
+
+ protected static void loadUtilityObjects(
+ Context ctx, RollerRequest rreq, RollerContext rollerCtx, String username)
+ throws RollerException
+ {
+ mLogger.debug("Loading utility objects");
+
+ // date formatter for macro's
+ // set this up with the Locale to make sure we can reuse it with other patterns
+ // in the macro's
+ Locale viewLocale = (Locale) ctx.get("viewLocale");
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd", viewLocale);
+ WebsiteData website = RollerFactory.getRoller().getUserManager().getWebsite(username);
+ if (website != null)
+ {
+ sdf.setTimeZone(website.getTimeZoneInstance());
+ }
+ // add formatter to context
+ ctx.put("dateFormatter", sdf );
+
+ // Note: in the macro's, the formats are taken from the ResourceBundles.
+ // Only the plainFormat is specified here, because it is used to render
+ // the Entry Day link.
+ ctx.put("plainFormat", "yyyyMMdd");
+
+ ctx.put("page", TemplateWrapper.wrap(rreq.getPage()));
+ ctx.put("utilities", new Utilities() );
+ ctx.put("stringUtils", new StringUtils() );
+ ctx.put("rollerVersion", rollerCtx.getRollerVersion() );
+ ctx.put("rollerBuildTime", rollerCtx.getRollerBuildTime() );
+ ctx.put("rollerBuildUser", rollerCtx.getRollerBuildUser() );
+ ctx.put("newsfeedCache", NewsfeedCache.getInstance() );
+
+ ctx.put("requestParameters", rreq.getRequest().getParameterMap());
+ }
+
+ //------------------------------------------------------------------------
+
+ protected static String loadWebsiteValues(
+ Context ctx, RollerRequest rreq, RollerContext rollerCtx )
+ throws RollerException
+ {
+ mLogger.debug("Loading website values");
+
+ String userName = null;
+ UserData user = null;
+ WebsiteData website = null;
+
+ Roller mRoller = RollerFactory.getRoller();
+ Map props = mRoller.getPropertiesManager().getProperties();
+
+ if ( rreq.getRequest().getAttribute(RollerRequest.OWNING_USER) != null)
+ {
+ user = (UserData)
+ rreq.getRequest().getAttribute(RollerRequest.OWNING_USER);
+ }
+ else if ( rreq.getUser() != null )
+ {
+ user = rreq.getUser();
+ }
+
+ if ( user != null )
+ {
+ userName = user.getUserName();
+ website = RollerFactory.getRoller().getUserManager().getWebsite(userName);
+ ctx.put("userName", user.getUserName() );
+ ctx.put("fullName", user.getFullName() );
+ ctx.put("emailAddress", user.getEmailAddress() );
+
+ ctx.put("encodedEmail", RegexUtil.encode(user.getEmailAddress()));
+ ctx.put("obfuscatedEmail", RegexUtil.obfuscateEmail(user.getEmailAddress()));
+
+ // setup Locale for future rendering
+ ctx.put("locale", website.getLocaleInstance());
+
+ // setup Timezone for future rendering
+ ctx.put("timezone", website.getTimeZoneInstance());
+ }
+ else
+ {
+ website = new WebsiteData();
+ website.setName(((RollerPropertyData)props.get("site.name")).getValue());
+ website.setAllowComments(Boolean.FALSE);
+ website.setDescription(((RollerPropertyData)props.get("site.description")).getValue());
+ userName = "zzz_none_zzz";
+ ctx.put("userName",userName );
+ ctx.put("fullName","zzz_none_zzz");
+ ctx.put("emailAddress",
+ ((RollerPropertyData)props.get("site.adminemail")).getValue());
+ ctx.put("locale", Locale.getDefault());
+ ctx.put("timezone", TimeZone.getDefault());
+ }
+ ctx.put("website", WebsiteDataWrapper.wrap(website) );
+
+ String siteName = ((RollerPropertyData)props.get("site.name")).getValue();
+ if ("Roller-based Site".equals(siteName)) siteName = "Main";
+ ctx.put("siteName", siteName);
+
+ // add language of the session (using locale of viewer set by Struts)
+ ctx.put(
+ "viewLocale",
+ LanguageUtil.getViewLocale(rreq.getRequest()));
+ mLogger.debug("context viewLocale = "+ctx.get( "viewLocale"));
+
+ return userName;
+ }
+
+ //------------------------------------------------------------------------
+
+ /**
+ * Initialize PagePlugins declared in web.xml. By using the full class
+ * name we also allow for the implementation of "external" Plugins
+ * (maybe even packaged seperately). These classes are then later
+ * instantiated by PageHelper.
+ *
+ * @param mContext
+ */
+ public static void initializePagePlugins(ServletContext mContext)
+ {
+ mLogger.debug("Initializing page plugins");
+
+ String pluginStr = RollerConfig.getProperty("plugins.page");
+ if (mLogger.isDebugEnabled()) mLogger.debug(pluginStr);
+ if (pluginStr != null)
+ {
+ String[] plugins = StringUtils.stripAll(
+ StringUtils.split(pluginStr, ",") );
+ for (int i=0; i<plugins.length; i++)
+ {
+ if (mLogger.isDebugEnabled()) mLogger.debug("try " + plugins[i]);
+ try
+ {
+ Class pluginClass = Class.forName(plugins[i]);
+ if (isPagePlugin(pluginClass))
+ {
+ mPagePlugins.add(pluginClass.newInstance());
+ }
+ else
+ {
+ mLogger.warn(pluginClass + " is not a PagePlugin");
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ mLogger.error("ClassNotFoundException for " + plugins[i]);
+ }
+ catch (InstantiationException e)
+ {
+ mLogger.error("InstantiationException for " + plugins[i]);
+ }
+ catch (IllegalAccessException e)
+ {
+ mLogger.error("IllegalAccessException for " + plugins[i]);
+ }
+ }
+ }
+ }
+
+ /**
+ * @param pluginClass
+ * @return
+ */
+ private static boolean isPagePlugin(Class pluginClass)
+ {
+ Class[] interfaces = pluginClass.getInterfaces();
+ for (int i=0; i<interfaces.length; i++)
+ {
+ if (interfaces[i].equals(PagePlugin.class)) return true;
+ }
+ return false;
+ }
+
+ public static boolean hasPlugins()
+ {
+ mLogger.debug("mPluginClasses.size(): " + mPagePlugins.size());
+ return (mPagePlugins != null && mPagePlugins.size() > 0);
+ }
+
+ public static List getPagePlugins()
+ {
+ return mPagePlugins;
+ }
+
+
+ private static final String TOOLBOX_KEY =
+ "org.roller.presentation.velocity.toolbox";
+
+ private static final String TOOLBOX_MANAGER_KEY =
+ "org.roller.presentation.velocity.toolboxManager";
+
+ private static ToolboxContext loadToolboxContext(
+ HttpServletRequest request, HttpServletResponse response, Context ctx)
+ {
+ mLogger.debug("Loading toolbox context");
+
+ ServletContext servletContext = RollerContext.getServletContext();
+
+ // get the toolbox manager
+ ServletToolboxManager toolboxManager =
+ (ServletToolboxManager)servletContext.getAttribute(TOOLBOX_MANAGER_KEY);
+ if (toolboxManager==null)
+ {
+ String file = RollerConfig.getProperty("velocity.toolbox.file");
+ mLogger.debug("Creating new toolboxContext using config-file: "+file);
+ toolboxManager = ServletToolboxManager.getInstance(servletContext, file);
+ servletContext.setAttribute(TOOLBOX_MANAGER_KEY, toolboxManager);
+ }
+
+ // load a toolbox context
+ ChainedContext chainedContext =
+ new ChainedContext(ctx, request, response, servletContext);
+ ToolboxContext toolboxContext =
+ toolboxManager.getToolboxContext(chainedContext);
+
+ if (toolboxContext != null)
+ {
+ // add MessageTool to VelocityContext
+ ctx.put("text", toolboxContext.internalGet("text"));
+
+ /*
+ Object[] keys = toolboxContext.internalGetKeys();
+ for (int i=0;i<keys.length;i++) {
+ String key = (String)keys[i];
+ System.out.println("key = "+key);
+ Object tool = toolboxContext.get(key);
+ System.out.println("tool = "+tool);
+ ctx.put(key, tool);
+ }
+ */
+ }
+
+ return toolboxContext;
+ }
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/DefaultCommentAuthenticator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/DefaultCommentAuthenticator.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/DefaultCommentAuthenticator.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/DefaultCommentAuthenticator.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,28 @@
+package org.roller.presentation.velocity;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.velocity.context.Context;
+import org.roller.pojos.CommentData;
+
+/**
+ * Default authenticator does nothing, always returns true.
+ * @author David M Johnson
+ */
+public class DefaultCommentAuthenticator implements CommentAuthenticator
+{
+ public String getHtml(
+ Context context,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ {
+ return "<!-- custom authenticator would go here -->";
+ }
+
+ public boolean authenticate(
+ CommentData comment,
+ HttpServletRequest request)
+ {
+ return true;
+ }
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/ExportRss.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/ExportRss.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/ExportRss.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/ExportRss.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,231 @@
+package org.roller.presentation.velocity;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.roller.RollerException;
+import org.roller.model.RollerFactory;
+import org.roller.pojos.UserData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.RollerContext;
+import org.roller.util.RegexUtil;
+import org.roller.util.StringUtils;
+import org.roller.util.Utilities;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.TimeZone;
+
+/**
+ * Does a lot of the same work as ContextLoader in preparing
+ * a VelocityContext for parsing. However, it is ignorant of
+ * any HttpServletRequest related features, and so has
+ * considerably trimmed down information.
+ *
+ * Created on Mar 25, 2004
+ * @author lance.lavandowska
+ */
+public class ExportRss
+{
+ private VelocityEngine ve = null;
+ private VelocityContext ctx = null;
+ private UserData user = null;
+ private boolean exportAtom;
+
+ private static final String RSS_TEMPLATE = "org/roller/presentation/velocity/export_rss.vm";
+ private static final String ATOM_TEMPLATE = "org/roller/presentation/velocity/export_atom.vm";
+
+ public ExportRss(WebsiteData website) throws Exception
+ {
+ Properties props = new Properties();
+ props.load(RollerContext.getServletContext().
+ getResourceAsStream("/WEB-INF/velocity.properties"));
+ ve = new VelocityEngine();
+ ve.info("*******************************************");
+ ve.info("Initializing VelocityEngine for ExportRss");
+ ve.init( props );
+ ve.info("Done initializing VelocityEngine for ExportRss");
+ ve.info("************************************************");
+
+ ctx = new VelocityContext();
+
+ user = website.getUser();
+ RollerContext rollerCtx = RollerContext.getRollerContext(
+ RollerContext.getServletContext());
+ loadPageHelper();
+
+ loadDates(website);
+
+ loadWebsiteInfo(rollerCtx, website);
+
+ loadTheRest(rollerCtx);
+ }
+
+ public void setExportAtom(boolean atom)
+ {
+ exportAtom = atom;
+ }
+
+ /**
+ * Export the given entries using export_rss.vm.
+ *
+ * @param entries
+ * @throws ResourceNotFoundException
+ * @throws ParseErrorException
+ * @throws Exception
+ */
+ public void exportEntries(Collection entries, String fileName) throws ResourceNotFoundException, ParseErrorException, Exception
+ {
+ ctx.put("entries", entries);
+
+ String templateFile = RSS_TEMPLATE;
+ if (exportAtom) templateFile = ATOM_TEMPLATE;
+ Template template = ve.getTemplate( templateFile, "utf-8" );
+ StringWriter sw = new StringWriter();
+ template.merge(ctx, sw);
+
+ writeResultsToFile((String)ctx.get("uploadPath"), sw, fileName);
+ }
+
+ /**
+ * @param sw
+ */
+ private void writeResultsToFile(String filePath, StringWriter sw, String fileName)
+ throws RollerException, IOException
+ {
+ filePath += "/" + user.getUserName();
+ new java.io.File( filePath ).mkdirs(); // create dir path on drive
+
+ filePath += "/" + fileName;
+
+ File outputFile = new java.io.File( filePath );
+ FileOutputStream out = null;
+ try
+ {
+ //outputFile.createNewFile();
+ out = new FileOutputStream( outputFile );
+ out.write( sw.toString().getBytes() );
+ out.flush();
+ }
+ catch ( FileNotFoundException e )
+ {
+ throw new RollerException( "Unable to write to: " + outputFile.getAbsolutePath(), e );
+ }
+ finally
+ {
+ try
+ {
+ if ( out != null )
+ {
+ out.close();
+ }
+ }
+ catch ( java.io.IOException ioe )
+ {
+ System.err.println( "ExportRss unable to close OutputStream" );
+ }
+ }
+ }
+
+ /**
+ * Load miscellaneous values into the Context.
+ * @param rollerCtx
+ */
+ private void loadTheRest(RollerContext rollerCtx)
+ {
+ ctx.put("utilities", new Utilities() );
+ ctx.put("stringUtils", new StringUtils() );
+ ctx.put("entryLength", new Integer(-1));
+ }
+
+ /**
+ * Load information pertaining to the Website and
+ * its associated User.
+ * @param rollerCtx
+ */
+ private void loadWebsiteInfo(RollerContext rollerCtx, WebsiteData website)
+ {
+ ctx.put("website", website);
+ ctx.put("userName", user.getUserName() );
+ ctx.put("fullName", user.getFullName() );
+ ctx.put("emailAddress", user.getEmailAddress() );
+
+ ctx.put("encodedEmail", RegexUtil.encode(user.getEmailAddress()));
+ ctx.put("obfuscatedEmail", RegexUtil.obfuscateEmail(user.getEmailAddress()));
+
+
+ // custom figureResourcePath() due to no "request" object
+ StringBuffer sb = new StringBuffer();
+ String uploadDir = null;
+ try {
+ uploadDir = RollerFactory.getRoller().getFileManager().getUploadDir();
+ } catch(Exception e) {}
+
+ ctx.put("uploadPath", uploadDir);
+ }
+
+ /**
+ * Load time-related information.
+ * @param website
+ */
+ private void loadDates(WebsiteData website)
+ {
+ try
+ {
+ // Add current time and last updated times to context
+ Date updateTime = RollerFactory.getRoller().getWeblogManager()
+ .getWeblogLastPublishTime( user.getUserName(), null );
+ ctx.put("updateTime", updateTime);
+ }
+ catch (RollerException e)
+ {
+ ctx.put("updateTime", new Date());
+ }
+ ctx.put("now", new Date());
+
+ // setup Locale for future rendering
+ Locale locale = website.getLocaleInstance();
+ ctx.put("locale", locale);
+
+ // setup Timezone for future rendering
+ ctx.put("timezone", website.getTimeZoneInstance());
+
+ // date formats need to be run through the Localized
+ // SimpleDateFormat and pulled back out as localized patterns.
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd", locale);
+ sdf.setTimeZone( (TimeZone)ctx.get("timezone") );
+ ctx.put("plainFormat", sdf.toLocalizedPattern());
+
+ sdf.applyPattern("EEEE MMMM dd, yyyy");
+ ctx.put("toStringFormat", sdf.toLocalizedPattern());
+
+ sdf.applyPattern("MMM dd yyyy, hh:mm:ss a z");
+ ctx.put("timestampFormat", sdf.toLocalizedPattern());
+
+ ctx.put("dateFormatter", sdf );
+ }
+ /**
+ * Create a PageHelper. Note that will have no values
+ * necessary in parsing a Web request (such as /page) -
+ * it is only useful for the restricted export_rss.vm
+ * and has no PagePlugins either. We want the exported
+ * Entry.text to be the raw values.
+ */
+ private void loadPageHelper()
+ {
+ // Add Velocity page helper to context
+ PageHelper pageHelper = new PageHelper(null, null, ctx);
+ // set no PagePlugins - we *do not* want to render them.
+ ctx.put("pageHelper", pageHelper );
+ }
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/FlavorServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/FlavorServlet.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/FlavorServlet.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/FlavorServlet.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,133 @@
+package org.roller.presentation.velocity;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.velocity.Template;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.roller.RollerException;
+import org.roller.presentation.RollerRequest;
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.JspFactory;
+import javax.servlet.jsp.PageContext;
+
+/////////////////////////////////////////////////////////////////////////////
+/**
+ * <p>Responsible for rendering RSS feeds and other "flavors" of output for a
+ * weblog.</p>
+ *
+ * <p>If Servlet is mapped to <code>/rss</code> and user has defined
+ * an RSS override page (i.e. a page named "_rss"), then that Velocity
+ * template will be used for rendering.</p>
+ *
+ * <p>If there is a request parameter named "flavor", then the Velocity
+ * template specified by that parameter will be used for rendering. For
+ * example if the flavor is "rss092" then the template at classpath
+ * "/flavors/rss092.vm" will be used for rendering.</p>
+ *
+ * <p>Otherwise, the template /flavors/rss.vm" will be used for rendering.</p>
+ *
+ * <p>Assumes that If-Modified-Since has already been handled.</p>
+ *
+ * @author David M Johnson
+ *
+ * @web.servlet name="RssServlet"
+ * @web.servlet-mapping url-pattern="/rss/*"
+ * @web.servlet-mapping url-pattern="/flavor/*"
+ */
+public class FlavorServlet extends VelocityServlet
+{
+ static final long serialVersionUID = -2720532269434186051L;
+
+ private static Log mLogger = LogFactory.getFactory()
+ .getInstance(RollerRequest.class);
+ public Template handleRequest(HttpServletRequest request,
+ HttpServletResponse response, Context ctx)
+ {
+ RollerRequest rreq = null;
+ try
+ {
+ rreq = RollerRequest.getRollerRequest(request,getServletContext());
+
+ // This is an ugly hack to fix the following bug:
+ // ROL-547: "Site wide RSS feed is your own if you are logged in"
+ String[] pathInfo = StringUtils.split(rreq.getPathInfo(),"/");
+ if (pathInfo.length < 1)
+ {
+ // If website not specified in URL, set it to null
+ rreq.setWebsite(null);
+ }
+ }
+ catch (RollerException e)
+ {
+ // An error initializing the request is considered to be a 404
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("RollerRequest threw Exception", e);
+ }
+ try
+ {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ }
+ catch (IOException e1)
+ {
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("IOException sending error", e);
+ }
+ }
+ return null;
+ }
+ try
+ {
+ // Needed to init request attributes, etc.
+ PageContext pageContext =
+ JspFactory.getDefaultFactory().getPageContext(
+ this, request, response, "", true, 8192, true);
+ rreq.setPageContext(pageContext);
+ ContextLoader.setupContext(ctx, rreq, response);
+
+ final String useTemplate;
+ PageModel pageModel = (PageModel)ctx.get("pageModel");
+ if ( request.getServletPath().endsWith("rss")
+ && pageModel.getPageByName("_rss") != null )
+ {
+ // If the request specified the "/rss" mapping and the
+ // user has defined an RSS override page, we will use that.
+ useTemplate = pageModel.getPageByName("_rss").getId();
+ }
+ else if (request.getParameter("flavor") != null)
+ {
+ // If request specifies a "flavor" then use that.
+ String flavor = request.getParameter("flavor");
+ useTemplate = "/flavors/" + flavor + ".vm";
+ }
+ else
+ {
+ // Fall through to default RSS page template.
+ useTemplate = "/flavors/rss.vm";
+ }
+ return getTemplate(useTemplate);
+ }
+ catch (Exception e)
+ {
+ mLogger.error("ERROR in RssServlet", e);
+ }
+ return null;
+ }
+
+ //------------------------------------------------------------------------
+ /**
+ * Handle error in Velocity processing.
+ */
+ protected void error( HttpServletRequest req, HttpServletResponse res,
+ Exception e) throws ServletException, IOException
+ {
+ mLogger.warn("ERROR in FlavorServlet",e);
+ }
+}
+
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/FoafServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/FoafServlet.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/FoafServlet.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/FoafServlet.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,154 @@
+package org.roller.presentation.velocity;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.velocity.Template;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.roller.RollerException;
+import org.roller.model.UserManager;
+import org.roller.pojos.WeblogTemplate;
+import org.roller.pojos.UserData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.RollerContext;
+import org.roller.presentation.RollerRequest;
+import org.roller.util.Utilities;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * <p>Responsible for rendering FOAF feed. This servlet requires
+ * that the RequestFilter is in place for it, and should also
+ * have the IfModifiedFilter configured.</p>
+ *
+ * <p>Resources:<br />
+ * <a href="http://xmlns.com/foaf/0.1/"
+ * >FOAF Vocabulary Specification</a><br />
+ * <a href="http://www.xml.com/lpt/a/2004/02/04/foaf.html"
+ * >An Introduction to FOAF</a></p>
+ *
+ * <p>FOAF Autodiscovery: <br />
+ * <link rel="meta" type="application/rdf+xml" title="FOAF"
+ * href="$absBaseURL/foaf/$userName" /> </p>
+ *
+ * @author Lance Lavandowska
+ *
+ * @web.servlet name="FoafServlet"
+ * @web.servlet-mapping url-pattern="/foaf/*"
+ */
+public class FoafServlet extends VelocityServlet
+{
+ static final long serialVersionUID = -1893244416537298619L;
+
+ private static Log mLogger = LogFactory.getFactory()
+ .getInstance(RollerRequest.class);
+
+ /**
+ * This Velocity servlet does not make use of ContextLoader and associated
+ * classes (as do FlavorServlet and PageServlet) because that is more
+ * work than is really necessary. It implements its own setupContext()
+ * to load necessary values into the Velocity Context.
+ *
+ * @param ctx
+ * @param rreq
+ * @throws RollerException
+ */
+ public Template handleRequest(HttpServletRequest request,
+ HttpServletResponse response, Context ctx)
+ {
+ RollerRequest rreq = null;
+ try
+ {
+ rreq = RollerRequest.getRollerRequest(request, getServletContext());
+ }
+ catch (RollerException e)
+ {
+ // An error initializing the request is considered to be a 404
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("RollerRequest threw Exception", e);
+ }
+
+ try
+ {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ }
+ catch (IOException e1)
+ {
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("IOException sending error", e);
+ }
+ }
+ return null;
+ }
+
+ try
+ {
+ setupContext(ctx, rreq);
+
+ response.setContentType("application/rdf+xml");
+ return getTemplate("/flavors/foaf.vm");
+ }
+ catch (Exception e)
+ {
+ mLogger.error("ERROR in FoafServlet", e);
+ }
+ return null;
+ }
+
+ /**
+ * @param ctx
+ */
+ private void setupContext(Context ctx, RollerRequest rreq) throws RollerException
+ {
+ HttpServletRequest request = rreq.getRequest();
+ RollerContext rollerCtx = RollerContext.getRollerContext( request );
+
+ UserData user = rreq.getUser();
+ ctx.put("fullName", user.getFullName()); // name for FlavorServlet compatibility
+
+ // foaf:homepage to equal base URL for user
+ String homepage = Utilities.escapeHTML(
+ rollerCtx.getAbsoluteContextUrl(request) +
+ "/page/" + rreq.getUser().getUserName() );
+ ctx.put("websiteURL", homepage); // name for FlavorServlet compatibility
+
+ // see if foaf:weblog is different Page
+ WebsiteData website = rreq.getWebsite();
+ UserManager usrMgr = RollerContext.getRoller(request).getUserManager();
+ org.roller.pojos.Template weblog = website.getPageByName("Weblog");
+
+ // if weblog != homepage, add to context
+ if (weblog != null && !website.getDefaultPageId().equals(weblog.getId()))
+ {
+ String weblogUrl = Utilities.escapeHTML(
+ rollerCtx.getAbsoluteContextUrl(request) +
+ "/page/" + rreq.getUser().getUserName() +
+ "/" + weblog.getLink() );
+ ctx.put("weblog", weblogUrl);
+ }
+
+ // use SHA1 encrypted email address, including mailto: prefix
+ String shaEmail = Utilities.encodePassword(
+ "mailto:" + user.getEmailAddress(), "SHA");
+ ctx.put("shaEmail", shaEmail);
+ }
+
+ //------------------------------------------------------------------------
+ /**
+ * Handle error in Velocity processing.
+ */
+ protected void error( HttpServletRequest req, HttpServletResponse res,
+ Exception e) throws ServletException, IOException
+ {
+ mLogger.warn("ERROR in FoafServlet",e);
+ }
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/LanguageServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/LanguageServlet.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/LanguageServlet.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/LanguageServlet.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,121 @@
+/*
+ * Filename: LanguageServlet.java
+ *
+ * Created on 02-May-04
+ */
+package org.roller.presentation.velocity;
+
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.Globals;
+import org.apache.velocity.Template;
+import org.apache.velocity.context.Context;
+import org.roller.presentation.LanguageUtil;
+import org.roller.presentation.RollerContext;
+
+/**
+ * Changes the language of the current Locale to the language specified
+ * by the user. The new language must be supported by Roller.
+ *
+ * And new supported languages to the web.servlet-init-param value. Make sure you add language-only
+ * values at the end of a chain. So "en_US,en" instead of "en,en_US". And no spaces.
+ *
+ * @web.servlet name="LanguageServlet" load-on-startup="10"
+ * @web.servlet-init-param name="org.roller.presentation.supported.languages" value="en,nl,zh_cn,zh_tw,vi"
+ *
+ * @web.servlet-mapping url-pattern="/language/*"
+ *
+ * @author <a href="mailto:molen@mail.com">Jaap van der Molen</a>
+ * @version $Revision: 1.8 $
+ */
+public class LanguageServlet extends BasePageServlet
+{
+ static final long serialVersionUID = -6548723098429557183L;
+
+ /**
+ * Logger
+ */
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(LanguageServlet.class);
+
+ /**
+ * @see org.roller.presentation.velocity.BasePageServlet#init(javax.servlet.ServletConfig)
+ */
+ public void init(ServletConfig config) throws ServletException
+ {
+ super.init(config);
+
+ // load supported languages
+ ServletContext ctx = config.getServletContext();
+ String supportedLanguages =
+ config.getInitParameter(LanguageUtil.SUPPORTED_LANGUAGES);
+ if (supportedLanguages != null
+ && supportedLanguages.trim().length() > 0)
+ {
+ // extract langauges
+ ctx.setAttribute(
+ LanguageUtil.SUPPORTED_LANGUAGES,
+ LanguageUtil.extractLanguages(supportedLanguages));
+ }
+ }
+
+ /**
+ * @see org.roller.presentation.velocity.BasePageServlet#handleRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.apache.velocity.context.Context)
+ */
+ public Template handleRequest(
+ HttpServletRequest request,
+ HttpServletResponse response,
+ Context ctx) throws Exception
+ {
+ mLogger.debug("Processing language change...");
+ ServletContext servletContext = RollerContext.getServletContext();
+
+ Locale[] supportedLanguages =
+ LanguageUtil.getSupportedLanguages(servletContext);
+
+ if (supportedLanguages == null || supportedLanguages.length == 0)
+ {
+ // add error message
+ ctx.put("languageError", "Unable to switch language: no supported languages defined.");
+ // proceed with request serving
+ return super.handleRequest(request, response, ctx);
+ }
+
+ String newLang = request.getParameter("language");
+ mLogger.debug("New language in Request: " + newLang);
+ if (newLang == null || newLang.length() == 0) {
+ // add error message
+ ctx.put("languageError", "Unable to switch language: no new language specified.");
+ // proceed with request serving
+ return super.handleRequest(request, response, ctx);
+ }
+
+ Locale newLocale = LanguageUtil.createLocale(newLang);
+
+ // verify if new language is supported
+ if (!LanguageUtil.isSupported(newLocale, servletContext)) {
+ // add error message
+ ctx.put("languageError", "Unable to switch language: new language '"+newLang+"' is not supported.");
+ // proceed with request serving
+ return super.handleRequest(request, response, ctx);
+ }
+
+ // by now, all should be fine: change Locale
+ HttpSession session = request.getSession();
+ session.setAttribute(Globals.LOCALE_KEY, newLocale);
+ mLogger.debug("Changed language to: " + newLocale);
+
+ // proceed with request serving
+ return super.handleRequest(request, response, ctx);
+ }
+
+}