roller-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From snoopd...@apache.org
Subject svn commit: r189602 [21/50] - in /incubator/roller/trunk: ./ 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/src/org/roller/presentation/velocity/ contrib/plugins/src/org/roller/presentation/velocity/plugins/ contrib/plugins/src/org/roller/presentation/velocity/plugins/acronyms/ contrib/plugins/src/org/roller/presentation/velocity/plugins/bookmarks/ contrib/plugins/src/org/roller/presentation/velocity/plugins/email/ contrib/plugins/src/org/roller/presentation/velocity/plugins/jspwiki/ contrib/plugins/src/org/roller/presentation/velocity/plugins/radeox/ contrib/plugins/src/org/roller/presentation/velocity/plugins/readmore/ contrib/plugins/src/org/roller/presentation/velocity/plugins/smileys/ contrib/plugins/src/org/roller/presentation/velocity/plugins/textile/ docs/ docs/images/ docs/installguide/ docs/installguide/old/ docs/userguide/ docs/userguide/images/ docs/userguide/old/ metadata/ metadata/database/ metadata/database/hibernate/ metadata/xdoclet/ personal/ personal/eclipse/ personal/testing/ src/ src/org/ src/org/roller/ src/org/roller/business/ src/org/roller/business/hibernate/ src/org/roller/business/utils/ src/org/roller/model/ src/org/roller/pojos/ src/org/roller/presentation/ src/org/roller/presentation/atom/ src/org/roller/presentation/bookmarks/ src/org/roller/presentation/bookmarks/actions/ src/org/roller/presentation/bookmarks/formbeans/ src/org/roller/presentation/bookmarks/tags/ src/org/roller/presentation/filters/ src/org/roller/presentation/forms/ src/org/roller/presentation/newsfeeds/ src/org/roller/presentation/pagecache/ src/org/roller/presentation/pagecache/rollercache/ src/org/roller/presentation/tags/ src/org/roller/presentation/tags/calendar/ src/org/roller/presentation/tags/menu/ src/org/roller/presentation/velocity/ src/org/roller/presentation/weblog/ src/org/roller/presentation/weblog/actions/ src/org/roller/presentation/weblog/formbeans/ src/org/roller/presentation/weblog/search/ src/org/roller/presentation/weblog/search/operations/ src/org/roller/presentation/weblog/tags/ src/org/roller/presentation/website/ src/org/roller/presentation/website/actions/ src/org/roller/presentation/website/formbeans/ src/org/roller/presentation/website/tags/ src/org/roller/presentation/xmlrpc/ src/org/roller/util/ tests/ tests/org/ tests/org/roller/ tests/org/roller/business/ tests/org/roller/model/ tests/org/roller/persistence/ tests/org/roller/presentation/ tests/org/roller/presentation/atom/ tests/org/roller/presentation/bookmarks/ tests/org/roller/presentation/velocity/ tests/org/roller/presentation/velocity/plugins/ tests/org/roller/presentation/velocity/plugins/smileys/ tests/org/roller/presentation/velocity/plugins/textile/ tests/org/roller/presentation/xmlrpc/ tests/org/roller/util/ tools/ tools/buildtime/ tools/buildtime/mockrunner-0.2.6/ tools/buildtime/mockrunner-0.2.6/lib/ tools/buildtime/tomcat-4.1.24/ tools/buildtime/xdoclet-1.2/ tools/buildtime/xdoclet-1.2/lib/ tools/hibernate-2.1/ tools/hibernate-2.1/lib/ tools/lib/ tools/standard-1.0.3/ tools/standard-1.0.3/lib/ tools/standard-1.0.3/tld/ tools/struts-1.1/ tools/struts-1.1/lib/ web/ web/WEB-INF/ web/WEB-INF/classes/ web/WEB-INF/classes/flavors/ web/WEB-INF/classes/themes/ web/bookmarks/ web/images/ web/images/editor/ web/images/midas/ web/images/preview/ web/images/smileys/ web/tags/ web/templates/ web/theme/ web/theme/images/ web/theme/lavender/ web/theme/scripts/ web/theme/scripts/classes/ web/themes/ web/themes/basic/ web/themes/berkley/ web/themes/berkley/images/ web/themes/cheb/ web/themes/cheb/images/ web/themes/cheb/scripts/ web/themes/clean/ web/themes/currency-i18n/ web/themes/currency-i18n/images/ web/themes/currency/ web/themes/currency/images/ web/themes/grey2/ web/themes/moonshine/ web/themes/pacifica/ web/themes/robot/ web/themes/rolling/ web/themes/rolling/images/ web/themes/sotto/ web/themes/sotto/images/ web/themes/sotto/styles/ web/themes/sunsets/ web/themes/sunsets/images/ web/themes/sunsets/scripts/ web/themes/sunsets/styles/ web/themes/werner/ web/themes/x2/ web/themes/x2/images/ web/themes/x2/scripts/ web/themes/x2/styles/ web/weblog/ web/website/
Date Wed, 08 Jun 2005 16:06:46 GMT
Added: incubator/roller/trunk/src/org/roller/presentation/velocity/ContextLoader.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/velocity/ContextLoader.java?rev=189602&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/velocity/ContextLoader.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/velocity/ContextLoader.java Wed Jun  8 09:06:16 2005
@@ -0,0 +1,544 @@
+package org.roller.presentation.velocity;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+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.pojos.CommentData;
+import org.roller.pojos.PageData;
+import org.roller.pojos.RollerConfig;
+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.newsfeeds.NewsfeedCache;
+import org.roller.presentation.weblog.formbeans.CommentFormEx;
+import org.roller.util.RegexUtil;
+import org.roller.util.StringUtils;
+import org.roller.util.Utilities;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+/**
+ * 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 );
+        
+        // Add page model object to context                    
+        PageModel pageModel = new PageModel(rreq);
+        ctx.put("pageModel", pageModel );
+        ctx.put("pages", pageModel.getPages());
+        
+        // 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 ); 
+        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)
+    {
+        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) 
+    {
+        // if there is an "_entry" page, only load it once
+        PageModel pageModel = (PageModel)ctx.get("pageModel");
+        if (rreq.getWebsite() != null && pageModel != null) 
+        {
+            /* alternative display pages - customization */
+            PageData entryPage = pageModel.getUsersPageByName(rreq.getWebsite(), "_entry");
+            if (entryPage != null)
+            {
+                ctx.put("entryPage", entryPage);
+            }
+            PageData descPage = pageModel.getUsersPageByName(rreq.getWebsite(), "_desc");
+            if (descPage != null)
+            {
+                ctx.put("descPage", descPage);
+            }
+        }
+    }
+
+    private static String figureResourcePath( RollerRequest rreq )
+    {
+        HttpServletRequest request = rreq.getRequest();
+        RollerContext rCtx = RollerContext.getRollerContext( request );
+        RollerConfig  rollerConfig = rCtx.getRollerConfig();
+    
+        StringBuffer sb = new StringBuffer();
+        String uploadPath = rollerConfig.getUploadPath();
+        if ( uploadPath != null && uploadPath.trim().length() > 0 )
+        {
+            sb.append( uploadPath );
+        }
+        else
+        {
+            sb.append( request.getContextPath() );
+            sb.append( RollerContext.USER_RESOURCES );
+        }
+        return sb.toString();
+    }
+
+    //------------------------------------------------------------------------
+    
+    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
+    {
+        HttpServletRequest request = rreq.getRequest();
+        RollerConfig rollerConfig = rollerCtx.getRollerConfig();
+        
+        // Add comments related values to context
+        ctx.put("isCommentPage", Boolean.TRUE);
+        ctx.put("escapeHtml", rollerConfig.getEscapeCommentHtml() );
+        ctx.put("autoformat", rollerConfig.getAutoformatComments() );
+        
+        // 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("previewFromPage")!=null )
+        {
+            ArrayList list = new ArrayList();
+            CommentData cd = new CommentData();
+            commentForm.copyTo(cd, request.getLocale());
+            list.add(cd);
+            ctx.put("previewComments",list);            
+        }
+        else // Or the whole set of comment for the specified weblog entry
+        {
+            WeblogEntryData entry = rreq.getWeblogEntry();
+            ctx.put("entry",entry);            
+        }
+    }   
+
+    //------------------------------------------------------------------------
+    
+    protected static void loadPathValues(
+      Context ctx, RollerRequest rreq, RollerContext rollerCtx, String userName)
+    {
+        HttpServletRequest request = rreq.getRequest();
+        String url = null;
+        if ( userName != null )
+        {
+            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 ) );
+    }
+
+    //------------------------------------------------------------------------
+    
+    protected static void loadRequestParamKeys(Context ctx)
+    {
+        // 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
+    {
+        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)
+    {
+
+        // 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);
+        if (rreq.getWebsite() != null)
+        {
+            sdf.setTimeZone(rreq.getWebsite().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",            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(
+                                       rollerCtx.getRollerConfig()) );
+        
+        ctx.put("requestParameters", rreq.getRequest().getParameterMap());
+    }
+    
+    //------------------------------------------------------------------------
+    
+    protected static String loadWebsiteValues(
+        Context ctx, RollerRequest rreq, RollerContext rollerCtx )
+    {
+        String userName = null;
+        WebsiteData site = null;
+        if ( rreq.getUser() != null )
+        {
+            userName = rreq.getUser().getUserName();
+        }
+        
+        if ( userName != null )
+        {
+            site = rreq.getWebsite();
+            UserData user = rreq.getUser();
+            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", site.getLocaleInstance());
+           
+            // setup Timezone for future rendering
+            ctx.put("timezone", site.getTimeZoneInstance());
+        }
+        else
+        {
+            site = new WebsiteData();
+            site.setName(rollerCtx.getRollerConfig().getSiteName());
+            site.setAllowComments(Boolean.FALSE);
+            site.setDescription(
+                rollerCtx.getRollerConfig().getSiteDescription());
+            ctx.put("userName","Administrator" );
+            ctx.put("fullName","Administrator");
+            ctx.put("emailAddress",
+                rollerCtx.getRollerConfig().getEmailAddress());
+            ctx.put("locale", Locale.getDefault());
+            ctx.put("timezone", TimeZone.getDefault());
+        }
+        ctx.put("website", site );
+
+        String siteName = rollerCtx.getRollerConfig().getSiteName();
+        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)
+    {
+        String pluginStr = mContext.getInitParameter("org.roller.pagePlugins");
+        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.warn("ClassNotFoundException for " + plugins[i]);
+                }
+                catch (InstantiationException e)
+                {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+                catch (IllegalAccessException e)
+                {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+    
+    /**
+     * @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) 
+    {
+        ServletContext servletContext = request.getSession().getServletContext();
+
+        // get the toolbox manager
+        ServletToolboxManager toolboxManager = (ServletToolboxManager) servletContext.getAttribute(TOOLBOX_MANAGER_KEY);
+        if (toolboxManager==null) 
+        {
+            String file = servletContext.getInitParameter(TOOLBOX_KEY);
+            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/trunk/src/org/roller/presentation/velocity/ExportRss.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/velocity/ExportRss.java?rev=189602&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/velocity/ExportRss.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/velocity/ExportRss.java Wed Jun  8 09:06:16 2005
@@ -0,0 +1,3 @@
+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.RollerConfig;
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()));

        RollerConfig  rollerConfig = rollerCtx.getRollerConfig();
        
        // custom figureResourcePath() due to no "request" object
        StringBuffer sb = new StringBuffer();
        String uploadDir = rollerConfig.getUploadDir();
        if ( uploadDir != null && uploadDir.trim().length() > 0 )
        {
            sb.append( uploadDir );
        }
        else
        {
            String uploadPath = rollerConfig.getUploadPath();
            if (StringUtils.isEmpty(uploadPath)) 
                uploadPath = RollerContext.USER_RESOURCES;
            sb.append(RollerContext.getServletContext().getRealPath(uploadPath));
        }
        String path = sb.toString();
        //System.out.println("writing files to " + path);
        ctx.put("uploadPath", path);
    }

    /**
     * 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/trunk/src/org/roller/presentation/velocity/FlavorServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/velocity/FlavorServlet.java?rev=189602&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/velocity/FlavorServlet.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/velocity/FlavorServlet.java Wed Jun  8 09:06:16 2005
@@ -0,0 +1,12 @@
+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.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
{
    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());
        }
        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/trunk/src/org/roller/presentation/velocity/FoafServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/velocity/FoafServlet.java?rev=189602&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/velocity/FoafServlet.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/velocity/FoafServlet.java Wed Jun  8 09:06:16 2005
@@ -0,0 +1,2 @@
+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.PageData;
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
{
    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();
        PageData weblog = usrMgr.getPageByName(website, "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);
    }
}
\ No newline at end of file

Added: incubator/roller/trunk/src/org/roller/presentation/velocity/LanguageServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/velocity/LanguageServlet.java?rev=189602&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/velocity/LanguageServlet.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/velocity/LanguageServlet.java Wed Jun  8 09:06:16 2005
@@ -0,0 +1,123 @@
+/*
+ * Filename: LanguageServlet.java
+ * 
+ * Created on 02-May-04
+ */
+package org.roller.presentation.velocity;
+
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+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;
+
+/**
+ * Changes the language of the current Locale to the language specified
+ * by the user. The new language must be supported by Roller.  
+ * 
+ * @web.servlet name="LanguageServlet" load-on-startup="10"
+ * @web.servlet-init-param name="org.roller.presentation.supported.languages" value="en,nl,zh,vi"
+ *  
+ * @web.servlet-mapping url-pattern="/language/*"
+ * 
+ * @author <a href="mailto:molen@mail.com">Jaap van der Molen</a>
+ * @version $Revision: 1.5 $
+ */
+public class LanguageServlet extends BasePageServlet
+{
+	/**
+	 * 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
+			Vector lang = new Vector();
+			StringTokenizer st = new StringTokenizer(supportedLanguages, ",");
+			while (st.hasMoreTokens())
+			{
+				lang.add(st.nextToken());
+			}
+			mLogger.debug("supported languages: "+lang);
+			ctx.setAttribute(LanguageUtil.SUPPORTED_LANGUAGES, lang);
+		}
+	}
+
+	/**
+	 * @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
+	{
+		ServletContext servletContext =
+			request.getSession().getServletContext();
+		Vector supportedLanguages =
+			LanguageUtil.getSupportedLanguages(servletContext);
+		
+		if (supportedLanguages==null) 
+		{
+			// 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");
+		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);
+		}
+
+		// verify if new language is supported
+		if (!LanguageUtil.isSupported(newLang, 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,
+		// but preserve existing country
+		Locale existingLocale = LanguageUtil.getViewLocale(request);
+		Locale newLocale = new Locale(newLang, existingLocale.getCountry());
+
+		HttpSession session = request.getSession();
+		session.setAttribute(Globals.LOCALE_KEY, newLocale);
+		mLogger.debug("Changed language to: "+newLang);
+
+		// proceed with request serving
+		return super.handleRequest(request, response, ctx);
+
+	}
+
+}

Added: incubator/roller/trunk/src/org/roller/presentation/velocity/Macros.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/velocity/Macros.java?rev=189602&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/velocity/Macros.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/velocity/Macros.java Wed Jun  8 09:06:16 2005
@@ -0,0 +1,1088 @@
+
+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.VelocityContext;
+import org.apache.velocity.runtime.RuntimeSingleton;
+import org.roller.model.RefererManager;
+import org.roller.model.UserManager;
+import org.roller.pojos.PageData;
+import org.roller.pojos.RefererData;
+import org.roller.pojos.RollerConfig;
+import org.roller.pojos.UserData;
+import org.roller.pojos.WeblogCategoryData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.RollerContext;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.bookmarks.tags.ViewBookmarksTag;
+import org.roller.presentation.tags.menu.EditorNavigationBarTag;
+import org.roller.presentation.tags.menu.NavigationBarTag;
+import org.roller.presentation.weblog.tags.RssBadgeTag;
+import org.roller.presentation.weblog.tags.ViewWeblogEntriesTag;
+import org.roller.presentation.weblog.tags.WeblogCategoryChooserTag;
+import org.roller.util.Utilities;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.PageContext;
+
+/**
+ * Provides the macros object that is available to Roller templates and 
+ * weblog entries.
+ */
+public class Macros
+{
+    private static Log mLogger = 
+        LogFactory.getFactory().getInstance(Macros.class);
+
+    protected PageContext mPageContext = null;
+    
+    protected PageHelper mPageHelper = null;
+
+    /** Maximum depth of recursion for includePage and showWeblogEntry calls */
+    public static final int MAX_RECURSION_DEPTH = 6;
+    
+    /** Keep track of each thread's recursive depth in includePage(). */
+    protected static ThreadLocal mIncludePageTLS = new ThreadLocal();
+    
+    /** Keep track of each thread's recursive depth in showWeblogEntries(s */
+    protected static ThreadLocal mEntriesTLS = new ThreadLocal();
+    
+    /** Keep track of each thread's recursive depth in showWeblogEntries(s */
+    protected static ThreadLocal mEntriesDayTLS = new ThreadLocal();
+
+    //------------------------------------------------------------------------
+    /** Construts a macros object for a JSP page context. */
+    public Macros( PageContext ctx, PageHelper helper )
+    {
+        mPageContext = ctx;
+        mPageHelper = helper;
+    }
+
+    //------------------------------------------------------------------------
+    /** Get the Roller request object associated with this instance */
+    protected RollerRequest getRollerRequest()
+    {
+        return RollerRequest.getRollerRequest(mPageContext);
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Returns the current date formatted according to the specified pattern.
+     * @param pattern Date pattern, @see java.text.SimpleDateFormat
+     * @return Current date formatted according to specified pattern.
+     */
+    public String formatCurrentDate( String pattern )
+    {
+        String date = null;
+        try
+        {
+            SimpleDateFormat format = new SimpleDateFormat( pattern );
+            date = format.format( new Date() );
+        }
+        catch (RuntimeException e)
+        {
+            date = "ERROR: formatting date";
+        }
+        return date;
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Returns most recent update time of collection of weblog entries using
+     * the specified pattern.
+     * @param weblogEntries Collection of weblog entries.
+     * @param Date format pattern, @see java.text.SimpleDateFormat.
+     * @return Most recent update time formatted by pattern.
+     */
+    public String formatUpdateTime( ArrayList weblogEntries, String pattern )
+    {
+        String date = null;
+        Date updateTime = getUpdateTime(weblogEntries);
+        try
+        {
+            SimpleDateFormat format = new SimpleDateFormat( pattern );
+            date = format.format( updateTime );
+        }
+        catch (RuntimeException e)
+        {
+            date = "ERROR: formatting date";
+        }
+        return date;
+    }
+   
+    //------------------------------------------------------------------------
+    /**
+     * Returns most recent update time of collection of weblog entries.
+     * @param weblogEntries Collection of weblog entries.
+     * @return Most recent update time.
+     */
+    public Date getUpdateTime( ArrayList weblogEntries )
+    {
+        return PageModel.getUpdateTime( weblogEntries );
+    }
+   
+    //------------------------------------------------------------------------
+    /**
+     * Version number of Roller.
+     * @return Version number of Roller.
+     */
+    public String showVersion()
+    {
+        ServletContext ctx = mPageContext.getServletContext();
+        return ctx.getInitParameter( RollerContext.VERSION_KEY );
+    }
+    //------------------------------------------------------------------------
+    /**
+     * Title of your website.
+     * @return Title of your website.
+     */
+    public String showWebsiteTitle()
+    {
+        WebsiteData wd = null;
+        RollerRequest rreq = getRollerRequest();
+        try {
+            wd = rreq.getWebsite();
+        }
+        catch (Exception e) {
+            return "ERROR finding website in request: " + e.toString();
+        }
+        return wd.getName();
+    }
+    //------------------------------------------------------------------------
+    /**
+     * Website description.
+     * @return Website description.
+     */
+    public String showWebsiteDescription()
+    {
+        WebsiteData wd = null;
+        RollerRequest rreq = getRollerRequest();
+        try {
+            wd = rreq.getWebsite();
+        }
+        catch (Exception e) {
+            return "ERROR finding website in request: " + e.toString();
+        }
+        return wd.getDescription();
+    }
+    //------------------------------------------------------------------------
+    /**
+     * Show navigation links for pages that are not hidden.
+     * @param vertical Display links in a vertical column, separated by BR tags.
+     * @return HTML for navigation bar.
+     */
+    public String showNavBar( boolean vertical )
+    {
+        NavigationBarTag navTag = new NavigationBarTag();
+        navTag.setPageContext(mPageContext);
+        navTag.setVertical(vertical);
+        return navTag.emit();
+    }
+    //------------------------------------------------------------------------
+    /**
+     * Show navigation links for pages that are not hidden, separated by a
+     * specified delimeter.
+     * @param vertical Display links in a vertical column.
+     * @param delimeter Delimeter to separate links.
+     * @return HTML for navigation bar.
+     */
+    public String showNavBar( boolean vertical, String delimiter )
+    {
+        NavigationBarTag navTag = new NavigationBarTag();
+        navTag.setPageContext(mPageContext);
+        navTag.setVertical(vertical);
+        navTag.setDelimiter(delimiter);
+        return navTag.emit();
+    }
+    //------------------------------------------------------------------------
+    /**
+     * Show the Roller Editor menu as a navigation bar.
+     * specified delimeter.
+     * @param vertical Displaylinks in a vertical column.
+     * @return HTML for navigation bar.
+     * */
+    public String showEditorNavBar( boolean vertical )
+    {
+        EditorNavigationBarTag editorTag = new EditorNavigationBarTag();
+        editorTag.setPageContext(mPageContext);
+        if ( vertical )
+        {
+            editorTag.setView("/navbar-vertical.vm");
+        }
+        else
+        {
+            editorTag.setView("/navbar-horizontal.vm");
+        }
+        editorTag.setModel("editor-menu.xml");
+        return editorTag.emit();
+    }
+
+    //------------------------------------------------------------------------
+
+    /**
+     * Display bookmarks in specified folder using specified title.
+     * @param folderName Folder to be dislayed.
+     * @param title Title to be displayed.
+     * @return HTML for bookmarks display.
+     */
+    public String showBookmarks( String folderName, String title )
+    {
+        ViewBookmarksTag booksTag = new ViewBookmarksTag();
+        booksTag.setPageContext(mPageContext);
+        return booksTag.view( folderName, title );
+    }
+
+    /**
+     * Display bookmarks in specified folder using specified title.
+     * @param folderName Folder to be dislayed.
+     * @param showFolderName Display folder name as title.
+     * @return HTML for bookmarks display.
+     */
+    public String showBookmarks( String folderName, boolean showFolderName )
+    {
+        ViewBookmarksTag booksTag = new ViewBookmarksTag();
+        booksTag.setPageContext(mPageContext);
+        return booksTag.view( folderName, showFolderName );
+    }
+
+    /**
+     * Display bookmarks in specified folder as an expandable link.
+     * @param folderName Folder to be dislayed.
+     * @param showFolderName Display folder name as title.
+     * @param expandingFolder Show bookmarks in expanding folder.
+     * @return HTML and JavaScript for bookmarks display.
+     */
+    public String showBookmarks(
+        String folderName, boolean showFolderName, boolean expandingFolder )
+    {
+        ViewBookmarksTag booksTag = new ViewBookmarksTag();
+        booksTag.setPageContext(mPageContext);
+        return booksTag.view( folderName, showFolderName, expandingFolder );
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Get {@link org.roller.pojos.UserData UserData} object.
+     * @see org.roller.pojos.UserData
+     * @return User object.
+     */
+    public UserData getUser()
+    {
+        try
+        {
+            return getRollerRequest().getUser();
+        }
+        catch (Exception e)
+        {
+            mLogger.error("Getting user",e); 
+        }
+        return null;
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Get  
+     * {@link org.roller.presentation.users.WebsiteDataEx WebsiteDataEx} 
+     * object.
+     * @see org.roller.pojos.WebsiteData
+     * @return Website object.
+     */
+    public WebsiteData getWebsite()
+    {
+        try
+        {
+            return getRollerRequest().getWebsite();
+        }
+        catch (Exception e)
+        {
+            mLogger.error("Getting website",e); 
+        }
+        return null;
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Show weblog enties using the day template specified in your site 
+     * settings.
+     * @return HTML for weblog entries.
+     */    
+    public String showWeblogEntries()
+    {
+        return showWeblogEntries(15);
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Show up to 100 weblog enties using the day template specified in your site 
+     * settings.
+     * @param maxEntries Maximum number of entries to display.
+     * @return HTML for weblog entries.
+     */    
+    public String showWeblogEntries(int maxEntries)
+    {
+        String ret = null;
+        try
+        {
+            // protection from recursion
+            if ( mEntriesTLS.get() == null )
+            {
+                mEntriesTLS.set( new Integer(0) );
+            }
+            else
+            {
+                Integer countObj = (Integer)mEntriesTLS.get();
+                int count = countObj.intValue();
+                if ( count++ > MAX_RECURSION_DEPTH )
+                {
+                    return "ERROR: recursion level too deep";
+                }
+                mEntriesTLS.set( new Integer(count) );
+            }
+
+            if (maxEntries > 100) maxEntries = 100;
+
+            ViewWeblogEntriesTag entriesTag = new ViewWeblogEntriesTag();
+            entriesTag.setPageContext(mPageContext);
+            entriesTag.setMaxEntries(maxEntries);
+            ret = entriesTag.emit();
+        }
+        finally
+        {
+            mEntriesTLS.set( null );
+        }
+
+        return ret;
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Show most recent 15 weblog enties using specified day template.
+     * @param dayTemplate Name of day template.
+     * @return HTML for weblog entries.
+     */    
+    public String showWeblogEntries( String dayTemplate )
+    {
+        return showWeblogEntries(dayTemplate,15);
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Show weblog enties using specified day template.
+     * @param dayTemplate Name of day template.
+     * @param maxEntries Maximum number of entries to display.
+     * @return HTML for weblog entries.
+     */    
+    public String showWeblogEntries( String dayTemplate, int maxEntries )
+    {
+        String ret = null;
+        try
+        {
+            // protection from recursion
+            if ( mEntriesDayTLS.get() == null )
+            {
+                mEntriesDayTLS.set( new Integer(0) );
+            }
+            else
+            {
+                Integer countObj = (Integer)mEntriesDayTLS.get();
+                int count = countObj.intValue();
+                if ( count++ > MAX_RECURSION_DEPTH )
+                {
+                    return "ERROR: recursion level too deep";
+                }
+                mEntriesDayTLS.set( new Integer(count) );
+            }
+
+            ViewWeblogEntriesTag entriesTag = new ViewWeblogEntriesTag();
+            entriesTag.setPageContext(mPageContext);
+            entriesTag.setMaxEntries(maxEntries);
+            entriesTag.setDayTemplate( dayTemplate );
+            ret = entriesTag.emit();
+        }
+        finally
+        {
+            mEntriesDayTLS.set( null );
+        }
+        return ret;
+    }
+
+    //------------------------------------------------------------------------
+    /** 
+     * Display weblog calendar.
+     * @return HTML for calendar.
+     */
+    public String showWeblogCalendar()
+    {
+        return showWeblogCalendar(false);
+    }
+
+    //------------------------------------------------------------------------
+    /** 
+     * Display big weblog calendar, well suited for an archive page.
+     * @return HTML for calendar.
+     */
+    public String showBigWeblogCalendar()
+    {
+        return showWeblogCalendar(true);
+    }
+
+    //------------------------------------------------------------------------
+    /** 
+     * Weblog calendar display implementation.
+     * @param big Show big archive style calendar.
+     * @return HTML for calendar.
+     */
+    public String showWeblogCalendar( boolean big )
+    {
+    	return mPageHelper.showWeblogCalendar(big, null);
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Show a list of links to each of your weblog categores.
+     * @return HTML for category chooser.
+     */
+    public String showWeblogCategoryChooser()
+    {
+        WeblogCategoryChooserTag catTag = new WeblogCategoryChooserTag();
+        catTag.setPageContext(mPageContext);
+        return catTag.emit();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Show a list of links to each of your RSS feeds.
+     * @return HTML for RSS feed links.
+     */
+    public String showRSSLinks()
+    {
+        String links = "ERROR: creating RSS links";
+        try
+        {                
+            RollerRequest rreq = getRollerRequest();
+            RollerContext rctx = RollerContext.getRollerContext(
+                rreq.getServletContext());
+                
+            UserData ud = rreq.getUser();
+
+            String baseUrl = rctx.getContextUrl(
+                (HttpServletRequest)mPageContext.getRequest());
+            StringBuffer sb = new StringBuffer();
+
+
+            sb.append("<a href=\"");
+            sb.append( baseUrl );
+            sb.append("/rss/");
+            sb.append( ud.getUserName() );
+            sb.append("\">All</a> ");
+            sb.append("[<a href=\"");
+            sb.append( baseUrl );
+            sb.append("/rss/");
+            sb.append( ud.getUserName() );
+            sb.append("?excerpts=true\">");
+            sb.append("excerpts</a>]");
+            sb.append("<br />");
+
+			List cats = rreq.getRoller().getWeblogManager()
+                .getWeblogCategories(rreq.getWebsite(), false);
+			for (Iterator wbcItr = cats.iterator(); wbcItr.hasNext();) {
+				WeblogCategoryData category = (WeblogCategoryData) wbcItr.next();
+				String catName = category.getName();
+				sb.append("<a href=\"");
+				sb.append( baseUrl );
+				sb.append("/rss/");
+				sb.append( ud.getUserName() );
+				sb.append("?catname=");
+				sb.append( catName );
+				sb.append("\">");
+				sb.append( catName );
+				sb.append("</a> ");
+				sb.append("[<a href=\"");
+				sb.append( baseUrl );
+				sb.append("/rss/");
+				sb.append( ud.getUserName() );
+				sb.append("?catname=");
+				sb.append( catName );
+				sb.append("&amp;excerpts=true\">");
+				sb.append("excerpts</a>]");
+				sb.append("<br />");
+			}
+            
+            links = sb.toString();
+        }
+        catch (Exception e)
+        {
+            mLogger.error("Unexpected exception",e);
+        }
+        return links;
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Show RSS auto-discovery element.
+     * @return HTML for RSS auto-discovery element. 
+     */
+    public String showRSSAutodiscoveryLink()
+    {
+        String links = "ERROR: error generating RSS autodiscovery link";
+        try
+        {
+            RollerRequest rreq = RollerRequest.getRollerRequest(
+                (HttpServletRequest)mPageContext.getRequest());
+            RollerContext rctx = RollerContext.getRollerContext(
+                rreq.getServletContext());
+             
+            StringBuffer sb = new StringBuffer();
+            sb.append("<link rel=\"alternate\" type=\"application/rss+xml\" ");
+            sb.append("title=\"RSS\" href=\"");
+            sb.append( rctx.getContextUrl(
+                (HttpServletRequest)mPageContext.getRequest()) );
+            sb.append( "/rss/" );
+            sb.append( getUser().getUserName() );
+            sb.append( "\">" );
+            links = sb.toString();
+        }
+        catch (Throwable e)
+        {
+            mLogger.error("Showing RSS link",e);
+        }
+        return links;
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Show RSS badge with link to your main RSS feed.
+     * @return HTML for RSS badge with link to your main RSS feed.
+     */
+    public String showRSSBadge()
+    {
+        RssBadgeTag rssTag = new RssBadgeTag();
+        rssTag.setPageContext(mPageContext);
+        return rssTag.emit();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Expand macros in specified page and include the results in this page.
+     * @param Name of page to include.
+     * @return HTML for included page.
+     */
+    public String includePage( String pageName )
+    {
+        String ret = null;
+        try
+        {
+            // protection from recursion
+            if ( mIncludePageTLS.get() == null )
+            {
+                mIncludePageTLS.set( new Integer(0) );
+            }
+            else
+            {
+                Integer countObj = (Integer)mIncludePageTLS.get();
+                int count = countObj.intValue();
+                if ( count++ > MAX_RECURSION_DEPTH )
+                {
+                    return "ERROR: recursion level too deep";
+                }
+                mIncludePageTLS.set( new Integer(count) );
+            }            
+                       
+            // Get included page template 
+            RollerRequest rreq = RollerRequest.getRollerRequest(
+                (HttpServletRequest)mPageContext.getRequest());                
+            UserManager userMgr = rreq.getRoller().getUserManager();
+            
+            PageData pd = userMgr.getPageByName( 
+                rreq.getWebsite(), pageName );
+            Template vtemplate = null;
+            if (pd != null)
+            {
+                vtemplate = RuntimeSingleton.getTemplate( pd.getId() ); 
+            }
+            else
+            {
+                // maybe its in preview mode and doesn't exist yet?
+                vtemplate = RuntimeSingleton.getTemplate( pageName );                        
+            }
+            
+            if (vtemplate == null)
+            {
+                pageName =  pageName + " : No Page or Template found.";
+            }
+
+            // Run it through Velocity
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            VelocityContext vcontext = new VelocityContext();
+            ContextLoader.setupContext(vcontext,rreq,
+                (HttpServletResponse)mPageContext.getResponse());
+            
+            vtemplate.merge( vcontext, pw );           
+            ret = sw.toString();                      
+        } 
+        catch (Exception e)
+        {
+            ret = "ERROR: including page " + pageName;
+        } 
+        finally
+        {
+            mIncludePageTLS.set( null );
+        }
+        return ret;
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Shows HTML for an image in user's resource directory.
+     * @param fileName File name in resource directory
+     * @param linkUrl  URL that image links to, null or empty if none
+     * @param alt      Description of image and of link
+     * @param border   For IMG tag's border attribute
+     * @param halign   For IMG tag's halign attribute
+     * @param valign   For IMG tag's valign attribute
+     * @return String  HTML for displaying image
+     */
+    public String showResourceImage( String fileName, String linkUrl,
+        String alt, int border, String halign, String valign )
+    {
+        HttpServletRequest request =
+            (HttpServletRequest) mPageContext.getRequest();
+        String username = getRollerRequest().getUser().getUserName();
+        ServletContext app = mPageContext.getServletContext();
+        RollerConfig rollerConfig = 
+            RollerContext.getRollerContext( app ).getRollerConfig();
+
+        StringBuffer sb = new StringBuffer();
+        String uploadPath = rollerConfig.getUploadPath();
+        if ( uploadPath != null && uploadPath.trim().length() > 0 )
+        {
+            sb.append( uploadPath );
+            sb.append( "/");
+            sb.append( username );
+            sb.append( "/");
+            sb.append( fileName);
+        }
+        else
+        {
+            sb.append( request.getContextPath() );
+            sb.append( RollerContext.USER_RESOURCES );
+            sb.append( "/");
+            sb.append( username );
+            sb.append( "/");
+            sb.append( fileName);
+        }
+        return showImage( sb.toString(),linkUrl,alt,border,halign,valign );
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Shows HTML for an image in user's resource directory.
+     * @param imageUrl URL to image
+     * @param linkUrl  URL that image links to, null or empty if none
+     * @param alt      Description of image and of link
+     * @param border   For IMG tag's border attribute
+     * @param halign   For IMG tag's halign attribute
+     * @param valign   For IMG tag's valign attribute
+     * @return String  HTML for displaying image
+     */
+    public String showImage( String imageUrl, String linkUrl,
+        String alt, int border, String halign, String valign )
+    {
+        StringBuffer sb = new StringBuffer();
+        if ( linkUrl!=null && linkUrl.trim().length()>0 )
+        {
+            sb.append( "<a href=\"");
+            sb.append( linkUrl );
+            sb.append( "\" >");
+        }
+
+        sb.append("<img src=\"");
+        sb.append( imageUrl );
+        sb.append( "\" alt=\"");
+        sb.append( alt);
+        sb.append( "\" border=\"");
+        sb.append( border);
+        sb.append( "\" halign=\"");
+        sb.append( halign);
+        sb.append( "\" valign=\"");
+        sb.append( valign);
+        sb.append( "\" />");
+
+        if ( linkUrl!=null && linkUrl.trim().length()>0 )
+        {
+            sb.append( "</a>");
+        }
+
+        return sb.toString();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Gets path to images directory on your Roller server.
+     * @return Path to images directory on your Roller server.
+     */
+    public String showImagePath()
+    {
+        HttpServletRequest request =
+            (HttpServletRequest) mPageContext.getRequest();
+            
+        StringBuffer sb = new StringBuffer();
+        sb.append( request.getContextPath() );
+        sb.append( "/images" );
+        return sb.toString();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Gets path to your /resources directory, where you may have uploaded 
+     * files.
+     * @return Resource path.
+     */
+    public String showResourcePath()
+    {
+        HttpServletRequest request =
+            (HttpServletRequest) mPageContext.getRequest();
+            
+        String username = getRollerRequest().getUser().getUserName();
+        
+        ServletContext app = mPageContext.getServletContext();
+            RollerConfig rollerConfig = 
+                RollerContext.getRollerContext( app ).getRollerConfig();
+                
+        StringBuffer sb = new StringBuffer();
+        String uploadPath = rollerConfig.getUploadPath();
+        if ( uploadPath != null && uploadPath.trim().length() > 0 )
+        {
+            sb.append( uploadPath );
+        }
+        else
+        {
+            sb.append( request.getContextPath() );
+            sb.append( RollerContext.USER_RESOURCES );
+        }
+        sb.append( "/" );
+        sb.append( username );
+        return sb.toString();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * This is a convenience method to calculate the path to a theme. It
+     * basically adds a contextPath and the themes directory.
+     * @param Name of theme.
+     * @return Theme path.
+     */
+    public String showThemePath( String theme )
+    {
+        HttpServletRequest request =
+            (HttpServletRequest)mPageContext.getRequest();
+        StringBuffer sb = new StringBuffer();
+        sb.append( request.getContextPath());
+        sb.append( 
+            RollerContext.getRollerContext(request).
+                getRollerConfig().getUserThemes());
+        sb.append( "/" );
+        sb.append( theme );
+        return sb.toString();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * This is a convenience method to calculate the path to a theme image.
+     * @param theme Name of theme.
+     * @param imageName Name of image.
+     * @return Path to image in theme.
+     */    
+    public String showThemeImagePath( String theme, String imageName )
+    {
+        StringBuffer sb = new StringBuffer();
+        sb.append( showThemePath(theme));
+        sb.append( "/images/");
+        sb.append( imageName);
+        return sb.toString();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Display a theme image.
+     * @param theme Name of theme.
+     * @param imageName Name of image. 
+     * @return HTML for image.
+     */    
+    public String showThemeImage( String theme, String imageName )
+    {
+        StringBuffer sb = new StringBuffer();
+        sb.append( "<img alt=\""+imageName+"\" src=\"");
+        sb.append( showThemeImagePath(theme, imageName));
+        sb.append( "\"/>");
+        return sb.toString();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Return the path to a theme's styles directory.
+     * @param theme Name of theme.
+     * @param stylesheet Name of stylesheet.
+     * @return Theme style path.
+     */
+    public String showThemeStylePath( String theme, String stylesheet )
+    {
+        StringBuffer sb = new StringBuffer();
+        sb.append( showThemePath(theme));
+        sb.append( "/styles/");
+        sb.append( stylesheet);
+        return sb.toString();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Return HTML for referencing a theme.
+     * @param theme Name of theme
+     * @param stylesheet Name of stylesheet in theme.
+     * @param useImport Use import statement rather than link element.
+     * @return HTML for importing theme.
+     */
+    public String showThemeStyle(
+        String theme, String stylesheet, boolean useImport )
+    {
+        StringBuffer sb = new StringBuffer();
+        if (useImport) {
+            sb.append( "<style type=\"text/css\">");
+            sb.append( "@import url(");
+            sb.append( showThemeStylePath(theme, stylesheet));
+            sb.append( ");");
+            sb.append( "</style>");
+        } else {
+            sb.append( "<link rel=\"stylesheet\" type=\"text/css\" href=\"");
+            sb.append( showThemeStylePath(theme, stylesheet));
+            sb.append( "\" />");
+        }
+        return sb.toString();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Convenience macro to import a stylesheet using the import statement.
+     * @param theme Theme name.
+     * @param stylesheet Name of stylesheet within theme.
+     * @return HTML for importing theme.
+     */
+    public String showThemeStyleImport( String theme, String stylesheet )
+    {
+        return showThemeStyle(theme, stylesheet, true);
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Return the path to a theme's scripts directory.
+     * @param theme Name of theme.
+     * @param scriptFile Name of script in theme.
+     * @return Path to theme.
+     */
+    public String showThemeScriptPath( String theme, String scriptFile )
+    {
+        StringBuffer sb = new StringBuffer();
+        sb.append( showThemePath(theme));
+        sb.append( "/scripts/");
+        sb.append( scriptFile);
+        return sb.toString();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Return the full HTML to use a scriptFile, for example:
+     * <pre>
+     * <script type="text/javascript" src="/themes/default/scripts/sample.js">
+     * </script>.
+     * </pre>
+     * @param theme Name of theme.
+     * @param scriptFile Name of script in theme.
+     * @return Path to theme.
+     */
+    public String showThemeScript( String theme, String scriptFile)
+    {
+        StringBuffer sb = new StringBuffer();
+        sb.append( "<script type=\"text/javascript\" src=\"");
+        sb.append( showThemeScriptPath(theme, scriptFile));
+        sb.append( "\"></script>"); // a /> doesn't work in IE
+        return sb.toString();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Return the title of the current Roller page being processed.
+     * @return Title of the current Roller page being processed.
+     */
+    public String showPageName()
+    {
+        PageData pd = null;
+        RollerRequest rreq = getRollerRequest();
+        try
+        {
+            pd = rreq.getPage();
+        }
+        catch (Exception e) {
+            return "ERROR finding page in request: " + e.toString();
+        }
+        return pd.getName();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Return the description of the current Roller page being processed.
+     * @return Description of the current Roller page being processed.
+     */
+    public String showPageDescription()
+    {
+        PageData pd = null;
+        RollerRequest rreq = getRollerRequest();
+        try
+        {
+            pd = rreq.getPage();
+        }
+        catch (Exception e)
+        {
+            return "ERROR finding page in request: " + e.toString();
+        }
+        return pd.getDescription();
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Return the updateTime of the current Roller page being processed.
+     * @return UpdateTime of the current Roller page being processed.
+     */
+    public String showPageUpdateTime()
+    {
+        PageData pd = null;
+        RollerRequest rreq = getRollerRequest();
+        try
+        {
+            pd = rreq.getPage();
+        }
+        catch (Exception e)
+        {
+            return "ERROR finding page in request: " + e.toString();
+        }
+        if (pd.getUpdateTime() == null) return "";
+        return pd.getUpdateTime().toString();
+    }
+
+    //------------------------------------------------------------------------
+    /** 
+     * Show list of links to today's biggest referers. Shows up to up 
+     * referers and limits each to 20 characters width.
+     * @return HTML to display referers.
+     */
+    public String showReferers()
+    {
+        return showReferers(15,20);
+    }
+
+    //------------------------------------------------------------------------
+    /** 
+     * Show list of links to today's biggest referers. Shows up to up 
+     * specified number referers and limits each to 20 characters width.
+     * @param max Maximum number of referers to display.
+     * @return HTML to display referers.
+     */
+    public String showReferers( int max )
+    {
+        return showReferers(max,20);
+    }
+
+    //------------------------------------------------------------------------
+    /** 
+     * Show list of links to today's biggest referers. Shows up to up 
+     * specified number referers and limits each to specified characters width.
+     * @param max Maximum number of referers to display.
+     * @param maxWidth Maximum width in characters of each referer.
+     * @return HTML to display referers.
+     */
+    public String showReferers( int max, int maxWidth )
+    {
+        try
+        {
+            RollerRequest rreq = getRollerRequest();
+            RefererManager refmgr = rreq.getRoller().getRefererManager();
+
+            StringBuffer sb = new StringBuffer();
+            
+            sb.append("Today's Page Hits:");
+            sb.append( refmgr.getDayHits(rreq.getWebsite()) );
+            sb.append("<br/>");
+            sb.append("Total Page Hits:");
+            sb.append( refmgr.getTotalHits(rreq.getWebsite()) );
+            sb.append("<br/>");
+
+            List refs = refmgr.getTodaysReferers(rreq.getWebsite());
+            sb.append("");
+            sb.append("<ul class=\"rReferersList\">");
+            int count = refs.size()>max ? max : refs.size();
+            for (int i = 0; i < count; i++)
+            {
+            	RefererData data = (RefererData)refs.get(i);
+                sb.append("<li class=\"rReferersListItem\">");
+                sb.append( data.getDisplayUrl( maxWidth, true ) );
+                sb.append("</li>");
+            }
+            sb.append("</ul>");
+
+            return sb.toString();
+        }
+        catch (Exception e)
+        {
+            mLogger.error("Displaying referers list",e);
+            return "ERROR: displaying referers list";
+        }
+    }
+    
+    //------------------------------------------------------------------------
+    /**
+     * Remove occurences of HTML from a string. Does this by stripping out
+     * any text that exists between the characters "&lt;" and "&gt;".
+     * @param s String that may contain some HTML.
+     * @return String with no HTML.
+     */
+    public static String removeHTML(String s)
+    {
+        if ( s==null ) return "";
+        else return Utilities.removeHTML(s);
+    }
+
+    /** 
+     * Escape all characters that need to be escaped for HTML.
+     * @param s String that may contain some special HTML characters.
+     * @return String with special HTML characters escaped.
+     */
+    public static String escapeHTML( String s )
+    {
+        if ( s==null ) return "";
+        else return Utilities.escapeHTML(s);
+    }
+
+    /** Run both removeHTML and escapeHTML on a string.
+     * @param s String to be run through removeHTML and escapeHTML.
+     * @return String with HTML removed and HTML special characters escaped.
+     */
+    public static String removeAndEscapeHTML( String s )
+    {
+        if ( s==null ) return "";
+        else return Utilities.escapeHTML( removeHTML(s) );
+    }
+}
+
+



Mime
View raw message