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 [34/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/tags/calendar/CalendarTag.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/calendar/CalendarTag.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/calendar/CalendarTag.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/calendar/CalendarTag.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,358 @@
+
+package org.roller.presentation.tags.calendar;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.Globals;
+import org.apache.struts.config.ModuleConfig;
+import org.apache.struts.util.MessageResources;
+import org.apache.struts.util.RequestUtils;
+import org.roller.presentation.tags.HybridTag;
+import org.roller.util.DateUtil;
+
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.Tag;
+import org.roller.presentation.RollerContext;
+
+
+/**
+ * Calendar tag.
+ * @jsp.tag name="Calendar"
+ */
+public class CalendarTag extends HybridTag
+{
+    private static Log mLogger =
+        LogFactory.getFactory().getInstance(CalendarTag.class);
+
+    // JSP Attributes
+
+    /** @jsp.attribute required="true" */
+    public String getName() { return mName; }
+    public void setName( String name ) { mName = name; }
+    private String mName = null;
+
+    /* @jsp.attribute description="Date in yyyyMMdd format"
+    public String getDate() { return mDate; }
+    public void setDate( String s ) { mDate = s; }
+    private String mDate = null;
+    */
+
+    /** @jsp.attribute */
+    public String getModel() { return mModelName; }
+    public void setModel( String s ) { mModelName= s; }
+    private String mModelName = null;
+
+    /** @jsp.attribute */
+    public String getClassSuffix() { return mClassSuffix; }
+    public void setClassSuffix( String s ) { mClassSuffix= s; }
+    private String mClassSuffix = "";
+
+    // not a tag attribute
+    public void setLocale(Locale locale) {
+        if (locale != null)
+            mLocale = locale;
+    }
+    private Locale mLocale = Locale.getDefault();
+
+    // not a tag attribute
+    /*
+    private TimeZone mTimeZone = TimeZone.getDefault();
+    public void setTimeZone(TimeZone zone) {
+        if (zone != null)
+            mTimeZone = zone;
+    }
+    private TimeZone getTimeZone()
+    {
+        // I've seen TimeZone.getDefault() return null. -Lance
+        if (mTimeZone == null) 
+            mTimeZone = TimeZone.getTimeZone("America/New_York");
+        return mTimeZone;
+    }
+    */
+
+    private String[] mDayNames = null;
+
+    public CalendarTag()
+    {
+        /*
+         * Empty constructor.
+         *
+         * Used to build the day names, but the correct locale
+         * was not set at this stage. Day-name-building has moved to the
+         * doStartTag() method.
+         */
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Write to a PrintWriter so that tag may be used from Velocity
+     */
+    public int doStartTag( PrintWriter pw ) throws JspException
+    {
+        try
+        {
+            // build week day names
+            this.buildDayNames();
+
+            Date day=null;       // day to be displayed
+            Calendar dayCal;     // set to day to be displayed
+            Calendar cal;        // for iterating through days of month
+            Calendar todayCal;   // for iterating through days of month
+            CalendarModel model; // the calendar model
+
+            // ---------------------------------
+            // --- initialize date variables ---
+            // ---------------------------------
+
+            // check for parameter map and target url
+            StringTokenizer toker = new StringTokenizer(mModelName,".");
+            String tok1 = toker.nextToken();
+            if (toker.hasMoreTokens())
+            {
+                String tok2 = toker.nextToken();
+                Object bean = pageContext.findAttribute(tok1);
+                model = (CalendarModel)PropertyUtils.getProperty(bean, tok2);
+            }
+            else
+            {
+                model = (CalendarModel)pageContext.findAttribute( mModelName );
+            }
+            
+            // no model specified, nothing to generate
+            if (model == null)
+            {
+                return SKIP_BODY;
+            }
+            
+            day = model.getDay();
+
+            // ceate object to represent today
+            todayCal = model.getCalendar();
+            todayCal.setTime( new Date() );
+
+            // formatter Month-Year title of calendar
+            SimpleDateFormat formatTitle = new SimpleDateFormat("MMMM yyyy", mLocale);
+
+            HttpServletRequest request =
+                (HttpServletRequest)pageContext.getRequest();
+
+            // get Resource Bundle
+            MessageResources resources = getResources(request);
+
+            // go back to first day in month
+            cal = model.getCalendar();
+            day = DateUtil.getNoonOfDay(day, cal);
+            cal.set( Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DAY_OF_MONTH) );
+
+            // go back to sunday before that: the first sunday in the calendar
+            while ( cal.get( Calendar.DAY_OF_WEEK ) != Calendar.SUNDAY )
+            {
+                cal.add( Calendar.DATE, -1 );
+            }
+
+            // create table of 5 weeks, 7 days per row
+            dayCal = model.getCalendar();
+            dayCal.setTime( day );
+
+            // -------------------------
+            // --- draw the calendar ---
+            // -------------------------
+            pw.print("<table cellspacing=\"0\" border=\"0\" ");
+            pw.print(" summary=\""
+                +resources.getMessage(mLocale, "calendar.summary")
+                +"\" class=\"hCalendarTable"
+                +mClassSuffix+"\">");
+            pw.print("<tr>");
+            pw.print("<td colspan=\"7\" align=\"center\" "+
+                "class=\"hCalendarMonthYearRow"+mClassSuffix+"\">");
+            pw.print("<a href=\"" + model.computePrevMonthUrl()
+                     + "\" title=\"" + resources.getMessage(mLocale, "calendar.prev")
+                     + "\" class=\"hCalendarNavBar\">&laquo;</a> ");
+            pw.print( formatTitle.format(day) );
+            if (todayCal.getTime().compareTo(model.getNextMonth()) >= 0)
+            {    
+                pw.print(" <a href=\"" + model.computeNextMonthUrl()
+                     + "\" title=\"" + resources.getMessage(mLocale, "calendar.next")
+                     + "\" class=\"hCalendarNavBar\">&raquo;</a>");
+            }
+            pw.print("</td></tr>");
+
+            // emit the HTML calendar
+            for ( int w=-1; w<6; w++ )
+            {
+                pw.print("<tr>");
+                for ( int d=0; d<7; d++ )
+                {
+                    if ( w == -1 )
+                    {
+                        pw.print(
+                            "<th class=\"hCalendarDayNameRow"
+                            +mClassSuffix+"\" align=\"center\">");
+                        pw.print( mDayNames[d] );
+                        pw.print("</th>");
+                        continue;
+                    }
+
+                    // determine URL for this calendar day
+                    Date tddate = cal.getTime();
+                    String url = model.computeUrl( tddate, false );
+                    String content = model.getContent( tddate );
+
+                    if // day is today then use today style
+                        ((          cal.get(Calendar.DAY_OF_MONTH)
+                            == todayCal.get(Calendar.DAY_OF_MONTH))
+                        && (        cal.get(Calendar.MONTH)
+                            == todayCal.get(Calendar.MONTH))
+                        && (        cal.get(Calendar.YEAR)
+                            == todayCal.get(Calendar.YEAR)))
+                    {
+                        printToday(pw, cal, url, content);
+                    }
+                    else if // day is in calendar month
+                       ((cal.get(Calendar.MONTH) == dayCal.get(Calendar.MONTH))
+                     && (cal.get(Calendar.YEAR) == dayCal.get(Calendar.YEAR)))
+                    {
+                        printDayInThisMonth(pw, cal, url, content);
+                    }
+                    else // apply day-not-in-month style ;-)
+                    {
+                        printDayNotInMonth(pw, cal);
+                    }
+
+                    // increment calendar by one day
+                    cal.add( Calendar.DATE, 1 );
+                }
+                pw.print("</tr>");
+            }
+
+            pw.print("<tr class=\"hCalendarNextPrev"
+                +mClassSuffix+"\">");
+            pw.print("<td colspan=\"7\" align=\"center\">");
+
+            pw.print("<a href=\""+model.computeTodayMonthUrl()
+                +"\" class=\"hCalendarNavBar\">"
+                +resources.getMessage(mLocale, "calendar.today")
+                +"</a>");
+
+            pw.print("</td>");
+            pw.print("</tr>");
+
+            pw.print("</table>");
+        }
+        catch (Exception e)
+        {
+            pw.print("<span class=\"error\">");
+            pw.print("<p><b>An ERROR has occured CalendarTag</b></p>");
+            pw.print("</span>");
+            mLogger.error("Calendar tag exception",e);
+        }
+        return Tag.SKIP_BODY;
+    }
+
+    private void printDayNotInMonth(PrintWriter pw, Calendar cal)
+    {
+        pw.print("<td class=\"hCalendarDayNotInMonth"+mClassSuffix+"\">");
+        //pw.print(cal.get(Calendar.DAY_OF_MONTH));
+        pw.print("&nbsp;");
+        pw.print("</td>");
+    }
+    
+    private void printDayInThisMonth(PrintWriter pw, Calendar cal, String url, String content)
+    {
+        if ( content!=null )
+        {
+            pw.print("<td class=\"hCalendarDayCurrent"
+                +mClassSuffix+"\">");
+            pw.print( content );
+            pw.print("</td>");
+        }
+        else if (url!=null)
+        {
+            pw.print("<td class=\"hCalendarDayLinked"
+                +mClassSuffix+"\">");
+            pw.print("<div class=\"hCalendarDayTitle"
+                +mClassSuffix+"\">");
+            pw.print("<a href=\""+url+"\">");
+            pw.print(cal.get(Calendar.DAY_OF_MONTH));
+            pw.print("</a></div>");
+            pw.print("</td>");
+        }
+        else
+        {
+            pw.print("<td class=\"hCalendarDay"
+                +mClassSuffix+"\">");
+            pw.print("<div class=\"hCalendarDayTitle"
+                +mClassSuffix+"\">");
+            pw.print(cal.get(Calendar.DAY_OF_MONTH));
+            pw.print("</div>");
+            pw.print("</td>");
+        }
+    }
+    
+    private void printToday(PrintWriter pw, Calendar cal, String url, String content)
+    {
+        if ( content!=null )
+        {
+            pw.print("<td class=\"hCalendarDayCurrent"
+                +mClassSuffix+"\">");
+            pw.print( content );
+            pw.print("</td>");
+        }
+        else if (url!=null)
+        {
+            pw.print("<td class=\"hCalendarDayCurrent"
+               +mClassSuffix+"\">");
+            pw.print("<a href=\""+url+"\" "
+               +"class=\"hCalendarDayTitle"+mClassSuffix+"\">");
+            pw.print(cal.get(Calendar.DAY_OF_MONTH));
+            pw.print("</a>");
+            pw.print("</td>");
+        }
+        else
+        {
+            pw.print("<td class=\"hCalendarDayCurrent"
+                +mClassSuffix+"\">");
+            pw.print("<div class=\"hCalendarDayTitle"
+                +mClassSuffix+"\">");
+            pw.print(cal.get(Calendar.DAY_OF_MONTH));
+            pw.print("</div></td>");
+        }
+    }
+    private MessageResources getResources(HttpServletRequest request) {
+        ServletContext app = RollerContext.getServletContext();
+        ModuleConfig moduleConfig = RequestUtils.getModuleConfig(request, app);
+        return (MessageResources)app.getAttribute(Globals.MESSAGES_KEY +
+                                                  moduleConfig.getPrefix());
+    }
+
+    /**
+     * Helper method to build the names of the weekdays. This
+     * used to take place in the <code>CalendarTag</code> constructor,
+     * but there, <code>mLocale</code> doesn't have the correct value yet.
+     */
+    private void buildDayNames()
+    {
+        // build array of names of days of week
+        mDayNames = new String[7];
+        Calendar dayNameCal = Calendar.getInstance();
+        SimpleDateFormat dayFormatter = new SimpleDateFormat("EEE", mLocale);
+        dayNameCal.set(Calendar.DAY_OF_WEEK, 0);
+        for (int dnum = 0; dnum < 7; dnum++)
+        {
+            dayNameCal.add(Calendar.DATE, 1);
+            mDayNames[dnum] = dayFormatter.format(dayNameCal.getTime());
+        }
+    }
+
+}
+

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/calendar/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/calendar/package.html?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/calendar/package.html (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/calendar/package.html Fri Oct 21 14:27:36 2005
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title></title>
+</head>
+<body>
+JSP CalendarTag and CalendarModel
+
+</body>
+</html>

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/BaseRollerMenu.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/BaseRollerMenu.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/BaseRollerMenu.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/BaseRollerMenu.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,93 @@
+package org.roller.presentation.tags.menu;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.roller.RollerException;
+import org.roller.config.RollerConfig;
+import org.roller.presentation.RollerRequest;
+import org.roller.util.Utilities;
+
+/**
+ * Base class for Roller menu objects.
+ * @author Dave Johnson
+ */
+public abstract class BaseRollerMenu
+{
+    protected String mName = null;
+    protected String mEnabledProperty = null;
+    protected String mDisabledProperty = null;
+    protected List mRoles = new ArrayList();
+    
+    public BaseRollerMenu() {}
+    
+    public BaseRollerMenu(String name) { mName = name; }
+    
+    /** Name of menu */ 
+    public void setName( String v ) { mName = v; }
+
+    /** Name of menu */
+    public String getName() { return mName; }
+    
+    /** Roles allowed to use menu, comma separated */ 
+    public void setRoles( String roles ) 
+    {
+        mRoles = Arrays.asList(Utilities.stringToStringArray(roles,","));
+    }
+    
+    /** Name of property that enables menu (or null if always enabled) */
+    public void setEnabledProperty(String enabledProperty)
+    {
+        mEnabledProperty = enabledProperty;
+    }
+
+    /** Name of property that disable menu (or null if always enabled) */
+    public void setDisabledProperty(String disabledProperty)
+    {
+        mDisabledProperty = disabledProperty;
+    }
+    
+    /** Determine if menu  should be shown to use of specified request */
+    public boolean isPermitted(HttpServletRequest req) throws RollerException
+    {
+        if (mEnabledProperty != null) 
+        {
+            String enabledProp = RollerConfig.getProperty(mEnabledProperty);
+            if (enabledProp != null && enabledProp.equalsIgnoreCase("false"))
+            {
+                return false;
+            }
+        }
+        if (mDisabledProperty != null) 
+        {
+            String disabledProp = RollerConfig.getProperty(mDisabledProperty);
+            if (disabledProp != null && disabledProp.equalsIgnoreCase("true"))
+            {
+                return false;
+            }
+        }
+        if (mRoles != null && mRoles.size() > 0)
+        {
+            Iterator roles = mRoles.iterator();
+            while (roles.hasNext())
+            {
+                RollerRequest rreq = RollerRequest.getRollerRequest(req);
+                String role = (String)roles.next();
+                if (req.isUserInRole(role)) 
+                {
+                    return true;
+                }
+                else if (role.equals("admin") && rreq.isAdminUser()) 
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+        return true;
+    }
+}

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/EditorNavigationBarTag.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/EditorNavigationBarTag.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/EditorNavigationBarTag.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/EditorNavigationBarTag.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,58 @@
+
+package org.roller.presentation.tags.menu;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.presentation.RollerRequest;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.JspException;
+
+
+/**
+ * Draws the most complete possible Roller navigation bar based on request
+ * parameters userName, folderId and authenticated user (if there is one).
+ * @jsp.tag name="EditorNavigationBar"
+ */
+public class EditorNavigationBarTag extends MenuTag 
+{
+    private static Log mLogger = 
+        LogFactory.getFactory().getInstance(EditorNavigationBarTag.class);
+
+   	//------------------------------------------------------------- 
+	public EditorNavigationBarTag()
+	{
+	}
+
+   	//------------------------------------------------------------- 
+	public String view()
+	{
+		return emit();
+	}
+
+   	//------------------------------------------------------------- 
+    public int doEndTag(java.io.PrintWriter pw) throws JspException
+    {
+		try 
+		{
+			HttpServletRequest request = 
+				(HttpServletRequest)pageContext.getRequest(); 
+			RollerRequest rreq = RollerRequest.getRollerRequest(request);
+
+			if ( rreq.isUserAuthorizedToEdit() )
+			{
+				return super.doEndTag(pw);
+			}
+			else
+			{
+				return EVAL_PAGE;
+			}
+		}
+		catch (Exception e)
+		{
+			mLogger.error("EditorNavigationBarTag exception",e);
+			throw new JspException(e);
+		}
+    }
+}
+

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/Menu.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/Menu.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/Menu.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/Menu.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,37 @@
+
+package org.roller.presentation.tags.menu;
+import org.roller.RollerException;
+
+import javax.servlet.http.HttpServletRequest;
+
+/** An individual menu which contains MenuItems */ 
+public interface Menu 
+{
+	/** Name of Menu */
+	public String getName();
+
+	/** Collection of MenuItem objects contained in this menu */
+	public java.util.Vector getMenuItems();
+
+	/** Determine if this menu is selected based on request */
+	public boolean isSelected( HttpServletRequest req ) throws RollerException;
+
+	/** Get currently selected menu item in this menu */
+	public MenuItem getSelectedMenuItem( HttpServletRequest req ) throws RollerException;
+
+    /** Url to be displayed in menu */ 
+    public String getUrl( javax.servlet.jsp.PageContext pctx );
+    
+    /** Is user principal permitted to use this menu? */ 
+    public boolean isPermitted( HttpServletRequest req ) throws RollerException;
+    
+    /** Set roles allowed to use this menu (comma separated list). */ 
+    public void setRoles( String roles );
+
+    /** Name of true/false configuration property that enables this menu */ 
+    public void setEnabledProperty( String enabledProperty );
+
+    /** Name of true/false configuration property that disables this menu */ 
+    public void setDisabledProperty( String disabledProperty );
+}
+

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuImpl.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuImpl.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuImpl.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,181 @@
+
+package org.roller.presentation.tags.menu;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Vector;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import javax.servlet.jsp.PageContext;
+
+import org.roller.RollerException;
+import org.roller.util.Utilities;
+
+/////////////////////////////////////////////////////////////////////////
+
+/** MenuImpl model has collection of menus */
+public class MenuImpl extends BaseRollerMenu implements Menu 
+{
+	private String mMenuId = null;
+
+    /** Vector of MenuItemImpl objects */
+	Vector mMenuItems = new Vector();
+	
+	/** Is this the default menu? */
+	boolean mDefault = false;
+	
+	public MenuImpl() {}
+
+	/** Construct with name */
+	public MenuImpl(String n) { super(n); }
+	
+	/** Add MenuItemImpl to MenuImpl */
+	public void addItem( MenuItemImpl item ) { mMenuItems.addElement(item); };
+	
+	/** Parent menu's ID */ 
+	public void setMenuId( String v ) { mMenuId = v; }
+
+	/** Parent menu's ID */
+	public String getMenuId() { return mMenuId; }
+
+	/** Collection of MenuItemImpl objects */
+	public Vector getMenuItems() { return mMenuItems; }
+
+	/** Get currently selected menu item in this menu 
+	 * @throws RollerException*/
+	public MenuItem getSelectedMenuItem( HttpServletRequest req ) throws RollerException
+	{
+		return getSelectedMenuItem( req, true ) ;
+	}
+
+	/** 
+     * Get currently selected menu item in this menu 
+	 * @throws RollerException
+     */
+	public MenuItem getSelectedMenuItem( HttpServletRequest req, 
+			boolean returnDefault ) throws RollerException
+	{
+		MenuItemImpl def = null;
+		MenuItemImpl selected = null;
+		for ( int i=0; i<mMenuItems.size(); i++ ) 
+		{
+			MenuItemImpl item = (MenuItemImpl)mMenuItems.elementAt(i);
+			if ( item.isSelected( req ) )
+			{
+				selected = item;
+				break;
+			}
+		    // Set first permitted and enabled menu item in each menu as default
+			if ( item.isPermitted(req) && def == null)
+			{
+				def = item;
+			}
+		}
+		if ( selected != null )
+		{
+			return selected;
+		}
+		else if ( returnDefault )
+		{
+			return def;
+		}
+		else 
+		{
+			return null;
+		}
+	}
+    
+	/** 
+     * Get default menu item (first one that is permitted)
+	 * @throws RollerException
+     */
+	public MenuItem getDefaultMenuItem( HttpServletRequest req ) 
+        throws RollerException
+	{
+		MenuItemImpl def = null;
+		MenuItemImpl selected = null;
+		for ( int i=0; i<mMenuItems.size(); i++ ) 
+		{
+		    // Set first permitted and enabled menu item in each menu as default
+			MenuItemImpl item = (MenuItemImpl)mMenuItems.elementAt(i);
+			if (item.isPermitted(req) && def == null)
+			{
+				def = item;
+			}
+		}
+		return def;
+	}
+
+	/** 
+     * Is this menu selected? 
+	 * @throws RollerException
+     */ 
+	public boolean isSelected( HttpServletRequest req ) throws RollerException
+	{
+        boolean selected = false;
+        HttpSession ses = req.getSession(false);
+        
+        String menuKey = req.getParameter(RollerMenuModel.MENU_KEY );
+        if (null == menuKey) 
+        {
+            menuKey = (String)req.getAttribute(RollerMenuModel.MENU_KEY);
+        }
+        if (null == menuKey) 
+        {
+            menuKey = (String)ses.getAttribute(mMenuId+"_"+RollerMenuModel.MENU_KEY);
+        }
+
+        if (menuKey != null && menuKey.equals(mName)) 
+        {
+            selected = true;
+        }
+		else
+		{
+			if ( getSelectedMenuItem( req, false ) != null ) 
+			{
+				selected = true;
+			}
+		}
+
+		if ( ses != null && selected )
+		{
+			ses.setAttribute(mMenuId + "_" + RollerMenuModel.MENU_KEY, mName);
+		}
+
+		return selected;
+	}
+
+	/** Name of Struts forward menu item should link to */
+	public String getUrl( PageContext pctx ) 
+	{
+		String url = null;
+		try 
+		{
+			HttpServletRequest req = (HttpServletRequest)pctx.getRequest();
+			String surl = getDefaultMenuItem( req ).getUrl( pctx ); 
+			StringBuffer sb = new StringBuffer( surl ); 
+			if ( surl.indexOf("?") == -1 )
+			{
+				sb.append( "?" ); 
+			}
+			else
+			{
+				sb.append( "&amp;" ); 
+			}
+			sb.append( RollerMenuModel.MENU_KEY );
+			sb.append( "=" ); 
+			sb.append( getName() );	
+			url = sb.toString();
+		}
+		catch (Exception e)
+		{
+			pctx.getServletContext().log(
+				"ERROR in menu creating URL",e);
+		}
+		return url;
+	}
+
+}
+

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuItem.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuItem.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuItem.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuItem.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,20 @@
+
+package org.roller.presentation.tags.menu;
+import javax.servlet.http.HttpServletRequest;
+
+/** An individual menu item, contained in a Menu */ 
+public interface MenuItem 
+{
+	/** Name of menu */
+	public String getName();
+
+	/** Url to be displayed in menu */ 
+	public String getUrl( javax.servlet.jsp.PageContext pctx );
+
+	/** Determine if this menu item is selected */
+	public boolean isSelected( HttpServletRequest req );
+    
+    /** Name of true/false configuration property that enables this menu */ 
+    public void setEnabledProperty( String enabledProperty );
+}
+

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuItemImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuItemImpl.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuItemImpl.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuItemImpl.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,166 @@
+
+package org.roller.presentation.tags.menu;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import javax.servlet.jsp.PageContext;
+
+import org.apache.struts.config.ForwardConfig;
+import org.apache.struts.config.ModuleConfig;
+import org.apache.struts.util.RequestUtils;
+import org.roller.RollerException;
+import org.roller.presentation.RollerContext;
+
+
+/////////////////////////////////////////////////////////////////////////
+
+/** 
+ * MenuImpls has collection of menu items. Multiple menus can be used 
+ * in one session, but they must have unique names.
+ */ 
+public class MenuItemImpl extends BaseRollerMenu implements MenuItem
+{
+	private String mMenuId = null;
+	
+	/** Name of Struts forward */
+	String mForward = null;
+	
+	/** Is this the default menu? */
+	boolean mDefault = false;
+
+	//---------------------------------------------------
+
+	public MenuItemImpl() {}
+
+	/** Construct with name and Struts forward */
+	public MenuItemImpl(String n, String f) 
+    { 
+        super(n); 
+        mForward = f; 
+    }
+
+	/** Parent menu's ID */ 
+	public void setMenuId( String v ) { mMenuId = v; }
+
+	/** Parent menu's ID */
+	public String getMenuId() { return mMenuId; }
+
+	/** Struts forward */ 
+	public String getForward() { return mForward; }
+
+	/** Struts forward */ 
+	public void setForward( String forward ) { mForward = forward; }
+
+	/** Name of Struts forward menu item should link to */
+	public String getUrl( PageContext pctx ) 
+	{
+		String url = null;
+		try 
+		{
+			Hashtable params = RollerMenuModel.createParams(
+					(HttpServletRequest)pctx.getRequest());
+			params.put( RollerMenuModel.MENU_ITEM_KEY, getName() );
+
+			url = RequestUtils.computeURL( 
+				pctx, 
+				mForward, // forward
+				null,     // href
+				null,     // page
+				null,
+				params,   // params 
+				null,     // anchor
+				false );  // redirect
+		}
+		catch (Exception e)
+		{
+			pctx.getServletContext().log(
+				"ERROR in menu item creating URL",e);
+		}
+		return url;
+	}
+
+	/** Given a request, tells if menu item is selected */ 
+	public boolean isSelected( HttpServletRequest req )
+	{
+		boolean selected = false;
+        HttpSession ses = req.getSession(false);
+        
+        String itemKey = req.getParameter(RollerMenuModel.MENU_ITEM_KEY );
+        if (null == itemKey) 
+        {
+            itemKey = (String)req.getAttribute(RollerMenuModel.MENU_ITEM_KEY);
+        }
+        if (null == itemKey) 
+        {
+            itemKey = (String)ses.getAttribute(mMenuId+"_"+RollerMenuModel.MENU_ITEM_KEY);
+        }
+
+        if (itemKey != null && itemKey.equals(mName)) 
+        {
+            selected = true;
+        }
+		else
+		{
+			// Is this item's forward the one being requested?
+            ServletContext ctx = RollerContext.getServletContext();     
+			ModuleConfig mConfig = RequestUtils.getModuleConfig(req,ctx);
+			ForwardConfig fConfig = mConfig.findForwardConfig(mForward);						
+			if (fConfig != null)
+			{
+				// Is the forward path in the request's URL?
+				String url = req.getRequestURL().toString();
+				
+				if ( url.indexOf( fConfig.getPath() ) != -1 )
+				{
+					//  Yes it is, so return true - this item is selected
+					selected = true;
+				}
+				
+			}
+		}
+		if (ses != null && selected)
+		{
+			ses.setAttribute(mMenuId+"_"+RollerMenuModel.MENU_ITEM_KEY, mName);
+		}
+		return selected;
+	}
+
+}
+
+
+
+//// get menu key from request param or from cookie
+//String menuKeyName = mMenuId+"rmk";
+//String menuKey = req.getParameter("rmk");
+//if (menuKey == null) 
+//{
+//  Cookie menuCookie = RequestUtil.getCookie(req, menuKeyName);
+//  if (menuCookie != null)
+//  {
+//      menuKey = menuCookie.getValue();
+//      req.setAttribute("rmk", menuKey);
+//  }
+//}
+//// save menu key in cookie
+//RequestUtil.setCookie(res, menuKeyName, menuKey, req.getContextPath());
+//
+//// get menu item key from request param or from cookie
+//String itemKeyName = mMenuId+"rmik";
+//String itemKey = req.getParameter("rmik");
+//if (itemKey == null) 
+//{
+//  Cookie itemCookie = RequestUtil.getCookie(req, itemKeyName);
+//  if (itemCookie != null)
+//  {
+//      itemKey = itemCookie.getValue();
+//      req.setAttribute("rmik", itemKey);
+//  }
+//}
+//// save menu item key in cookie
+//RequestUtil.setCookie(res, itemKeyName, itemKey, req.getContextPath());
+        
+

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuModel.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuModel.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuModel.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuModel.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,20 @@
+
+package org.roller.presentation.tags.menu;
+import javax.servlet.http.HttpServletRequest;
+
+import org.roller.RollerException;
+
+
+/** Menu model contains Menus */ 
+public interface MenuModel 
+{
+	/** Collection of Menu objects contained in this menu model */
+	public java.util.Vector getMenus();
+
+	/** Return menu selected by current request or first menu.
+	 *  If request does not indicate a menu then first menu is returned.
+	 * @throws RollerException
+	 */
+	public Menu getSelectedMenu( HttpServletRequest req ) throws RollerException;
+}
+

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuTag.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuTag.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuTag.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/MenuTag.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,84 @@
+
+package org.roller.presentation.tags.menu;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.velocity.VelocityContext;
+import org.roller.RollerException;
+import org.roller.presentation.util.RequestUtil;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.tags.VelocityTag;
+import org.roller.presentation.velocity.ContextLoader;
+//import javax.servlet.jsp.tagext.*;
+
+
+/**
+ * @jsp.tag name="Menu"
+ */
+public class MenuTag extends VelocityTag 
+{
+	private static Log mLogger = 
+		LogFactory.getFactory().getInstance(RollerRequest.class);
+
+	/** Unique ID for this menu within the user's session. 
+	  * @jsp.attribute 
+	  */
+	public String getId() { return mMenuId; }
+    public void setId( String v ) { mMenuId= v; }
+	private String mMenuId;
+
+	/** Name of the view to be used to render the menu.
+      * The view is a Velocity template and it must be in the classpath. 
+	  * Values: tabbed, vertical, horizontal.
+	  * @jsp.attribute  required="true"
+	  */
+	public String getView() { return mView; }
+    public void setView( String v ) { mView = v; }
+	private String mView;
+
+	/** Name of the model to be used.
+	  * Must correspond to name of XML file in WEB-INF directory.
+	  * @jsp.attribute required="true"
+	  */
+	public String getModel() { return mModel; }
+    public void setModel( String v ) { mModel = v; }
+	private String mModel;
+
+    public String getTemplateClasspath()
+    {
+        return mView;
+    }
+
+   	//------------------------------------------------------------- 
+
+	public void prepareContext( VelocityContext ctx )
+	{
+		HttpServletRequest req = (HttpServletRequest)pageContext.getRequest();
+		HttpServletResponse res = (HttpServletResponse)pageContext.getResponse();
+
+		RollerMenuModel model = new RollerMenuModel( 
+			mMenuId, "/WEB-INF/"+mModel, pageContext.getServletContext() );
+		ctx.put("menuModel", model );
+		ctx.put("ctx", pageContext );
+		ctx.put("req", req );
+		ctx.put("res", res );
+		
+		RollerRequest rreq = RollerRequest.getRollerRequest(req);
+		rreq.setPageContext(pageContext);
+		try
+		{
+			ContextLoader.setupContext( ctx, rreq, res );
+		}
+		catch (RollerException e)
+		{
+			// superclass says I can't throw an exception
+			mLogger.error(e);
+		}
+	}
+
+}
+

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/NavigationBarTag.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/NavigationBarTag.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/NavigationBarTag.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/NavigationBarTag.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,178 @@
+package org.roller.presentation.tags.menu;
+
+import java.io.StringWriter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.TagSupport;
+
+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.app.Velocity;
+import org.roller.RollerException;
+import org.roller.presentation.RollerContext;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.velocity.ContextLoader;
+import org.roller.presentation.velocity.PageModel;
+
+/**
+ * Draws the most complete possible Roller navigation bar based on request
+ * parameters userName, folderId and authenticated user (if there is one).
+ * 
+ * By supplying a "view" attribute, you can replace the default display 
+ * with a custom implementation of the Navigation Bar.  Implement by
+ * creating a new VM file and placing it in /WEB-INF/classes.
+ * 
+ * @jsp.tag name="NavigationBar"
+ */
+public class NavigationBarTag extends MenuTag
+{
+    private static Log mLogger = 
+    	LogFactory.getFactory().getInstance(RollerRequest.class);
+    	
+    private boolean mVertical = false;
+    private String mDelimiter = "|";
+
+    /** @jsp.attribute */
+    public boolean getVertical()
+    {
+        return mVertical;
+    }
+
+    public void setVertical(boolean v)
+    {
+        mVertical = v;
+    }
+
+    /** @jsp.attribute */
+    public String getDelimiter()
+    {
+        return mDelimiter;
+    }
+
+    public void setDelimiter(String v)
+    {
+        mDelimiter = v;
+    }
+
+   /**
+    * Replace the 'standard' NavigationBar display with a custom vm file.
+    *
+    * @jsp.attribute  required="false"
+    */
+    public String getView() { return super.getView(); }
+    public void setView( String v ) 
+    { 
+        super.setView(v);
+    }
+
+    /** Name of the model to be used.
+      * Must correspond to name of XML file in WEB-INF directory.
+      * @jsp.attribute required="false"
+      */
+    public String getModel() { return super.getModel(); }
+    public void setModel( String v ) { super.setModel(v); }
+    
+    //-------------------------------------------------------------
+    public String view(boolean isVertical)
+    {
+        mVertical = isVertical;
+
+        return emit();
+    }
+    
+    public void prepareContext( VelocityContext ctx )
+    {
+        HttpServletRequest req = (HttpServletRequest)pageContext.getRequest();
+        HttpServletResponse res = (HttpServletResponse)pageContext.getResponse();
+
+        RollerRequest rreq = RollerRequest.getRollerRequest(req);
+        rreq.setPageContext(pageContext);
+        RollerContext rollerCtx = RollerContext.getRollerContext(req);
+        try 
+        {    
+            ContextLoader.setupContext( ctx, rreq, res );
+            PageModel pageModel = (PageModel)ctx.get("pageModel");
+            ctx.put("model", pageModel);            
+            ctx.put("pages", pageModel.getPages());            
+            ctx.put("req", req);
+            ctx.put("res", res);
+            ctx.put("vertical", Boolean.valueOf(getVertical()));
+            ctx.put("delimiter", getDelimiter());
+            ctx.put("editorui", Boolean.TRUE);            
+        }
+        catch (Exception e)
+        {
+            // superclass says I can't throw an exception
+            mLogger.error(e);
+        }
+    }
+
+    //-------------------------------------------------------------
+
+    /**
+     * Evaluate any tags inside us.  This will also allow us to have child tags
+     * send us messages.
+     * @return
+     * @throws JspException
+     */
+    public int doStartTag(java.io.PrintWriter pw)
+        throws JspException
+    {
+        return TagSupport.EVAL_BODY_INCLUDE;
+    }
+
+    /**
+     * @return
+     * @throws JspException
+     */
+    public int doEndTag(java.io.PrintWriter pw) throws JspException
+    {
+        try 
+        {
+            // a special view VM has been defined
+            if (getView() != null)
+            {
+                Template template = Velocity.getTemplate(
+                    getVelocityClasspathResource( getTemplateClasspath() ) );
+                VelocityContext context = getVelocityContext();
+                prepareContext( context );
+                template.merge(context, pw);
+                return EVAL_PAGE;
+            }
+            else
+            {
+                //setView("/navbar.vm");
+                //String myResource= getVelocityClasspathResource(getTemplateClasspath());
+                
+                String myResource= getVelocityClasspathResource("/navbar.vm");
+
+                VelocityContext myVelocityContext = getVelocityContext();
+
+                // ask concrete class to prepare context 
+                prepareContext( myVelocityContext );
+                if (myVelocityContext.get("pageHelper") == null)
+                    throw new RollerException("Failure initializing ContextLoader.");
+
+                StringWriter myStringWriter = new StringWriter();
+                
+                String[] vars = {"vertical", "delimiter" };
+                Velocity.invokeVelocimacro("showNavBar", "NavigationBar", vars, 
+                    myVelocityContext, myStringWriter);
+
+                pw.println(myStringWriter);
+
+                return EVAL_PAGE;
+
+            }
+        }
+        catch (Exception e)
+        {
+            mLogger.error("EditorNavigationBarTag exception",e);
+            throw new JspException(e);
+        }
+    }
+}
\ No newline at end of file

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/RollerMenuModel.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/RollerMenuModel.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/RollerMenuModel.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/RollerMenuModel.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,187 @@
+
+package org.roller.presentation.tags.menu;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.RollerException;
+import org.roller.config.RollerConfig;
+import org.roller.pojos.UserData;
+import org.roller.presentation.RollerRequest;
+import org.xml.sax.SAXException;
+
+import java.io.InputStream;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+
+//////////////////////////////////////////////////////////////////////////////
+
+/** 
+ * @author David M Johnson
+ */ 
+public class RollerMenuModel extends BaseRollerMenu implements MenuModel
+{
+    private static Log mLogger = 
+        LogFactory.getFactory().getInstance(RollerMenuModel.class);
+        
+	private String mMenuId = null;
+
+	/** Vector of MenuImpl objects */
+	private Vector mMenus = new Vector();
+
+	/** Key used to store selected menu in request */
+	public static final String MENU_KEY = "rmk";
+
+	/** Key used to store selected menu item in request */
+	public static final String MENU_ITEM_KEY = "rmik";
+
+	//------------------------------------------------------------------------
+
+	/** Construct menu model based on menu XML */	
+	public RollerMenuModel( String menuId, String config, ServletContext ctx )
+	{
+		try
+		{
+			mMenuId = menuId;
+
+			Digester digester = new Digester();
+			digester.push(this);
+			//digester.setDebug(99);
+			//digester.setClassLoader( getClass().getClassLoader() );
+			//digester.setValidating(true);
+
+			String menuPath = "menu-bar/menu";
+			String menuItemPath = "menu-bar/menu/menu-item";
+
+			digester.addObjectCreate( menuPath,
+			 	"org.roller.presentation.tags.menu.MenuImpl");
+			digester.addSetProperties( menuPath );
+			digester.addSetNext( menuPath,"addMenu",
+			 	"org.roller.presentation.tags.menu.Menu");
+
+			digester.addObjectCreate( menuItemPath,
+			 	"org.roller.presentation.tags.menu.MenuItemImpl");
+			digester.addSetProperties( menuItemPath );
+			digester.addSetNext( menuItemPath, "addItem",
+			 	"org.roller.presentation.tags.menu.MenuItemImpl");
+
+			InputStream input = ctx.getResourceAsStream(config);
+			try 
+			{
+				digester.parse(input);
+
+				if ( getMenus() != null )
+				{
+					Vector menus = getMenus();
+					for (int i=0; i<menus.size(); i++)
+					{
+						MenuImpl menu = (MenuImpl)menus.elementAt(i);
+						menu.setMenuId( mMenuId );
+						Vector menuItems = menu.getMenuItems();
+						if ( menuItems != null )
+						{
+						  for (int j=0; j<menuItems.size(); j++ )
+						  {
+							  MenuItemImpl item = 
+							  	(MenuItemImpl)menuItems.elementAt(j);
+							  item.setMenuId( mMenuId );
+						  }
+						}
+					}
+				}
+			} 
+			catch (SAXException e) 
+			{
+                mLogger.error("Unexpected exception",e);
+			}
+            finally 
+            {
+                if ( input!=null )
+                {
+                    try { input.close(); } 
+                    catch (Exception e) { mLogger.error("Unexpected exception",e); };
+                }
+            }
+		}	
+		catch (Exception e)
+       	{
+            mLogger.error("Unexpected exception",e);
+		}
+	}
+
+	//----------------------------------------------- MenuModel implementation
+
+	public Vector getMenus()
+	{
+		return mMenus;
+	}
+
+	//----------------------------------------------------
+	public Menu getSelectedMenu( HttpServletRequest req ) throws RollerException
+	{
+		MenuImpl def = null;
+		MenuImpl selected = null; 
+		for ( int i=0; i<mMenus.size(); i++ ) 
+		{
+			MenuImpl menu = (MenuImpl)mMenus.elementAt(i);
+			if ( menu.isSelected( req ) )
+			{
+				selected = menu;
+				break;
+			}
+			if (def == null)
+			{
+				def = menu;
+			}
+		}
+		if ( selected != null )
+		{
+			return selected;
+		}
+		else
+		{
+			return def;
+		}
+	}
+
+	//----------------------------------------------------
+	public void addMenu( Menu menu )
+	{
+		mMenus.addElement( menu );
+	}
+
+	//------------------------------------------------------------------------
+
+	/** Create params based on incoming request */
+	static Hashtable createParams( HttpServletRequest req )
+	{
+		Hashtable params = new Hashtable();
+		RollerRequest rreq = RollerRequest.getRollerRequest(req);
+		try
+		{
+			UserData user = rreq.getUser();
+			String fid = 
+                rreq.getFolder()==null ? null : rreq.getFolder().getId();
+			if ( user != null ) 
+			{
+				params.put( RollerRequest.USERNAME_KEY, user.getUserName() );
+			}
+			if ( fid != null ) 
+			{
+				params.put( RollerRequest.FOLDERID_KEY, fid );
+			}
+		}
+		catch (Exception e)
+		{
+			mLogger.error("ERROR getting user in menu model", e);
+		}
+		return params;
+	}
+}
+
+

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/package.html?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/package.html (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/menu/package.html Fri Oct 21 14:27:36 2005
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title></title>
+</head>
+<body>
+Roller's tabbed menu implementation (menu's defined by XML)
+
+</body>
+</html>

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/package.html?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/package.html (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/tags/package.html Fri Oct 21 14:27:36 2005
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title></title>
+</head>
+<body>
+JSP tags used in Roller UI.
+
+</body>
+</html>

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/util/RequestUtil.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/util/RequestUtil.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/util/RequestUtil.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/util/RequestUtil.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,261 @@
+package org.roller.presentation.util;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.taglib.TagUtils;
+
+/**
+ * RequestUtil utility class Good ol' copy-n-paste from <a
+ * href="http://www.javaworld.com/javaworld/jw-02-2002/ssl/utilityclass.txt">
+ * http://www.javaworld.com/javaworld/jw-02-2002/ssl/utilityclass.txt </a> which
+ * is referenced in the following article: <a
+ * href="http://www.javaworld.com/javaworld/jw-02-2002/jw-0215-ssl.html">
+ * http://www.javaworld.com/javaworld/jw-02-2002/jw-0215-ssl.html </a>
+ */
+public class RequestUtil
+{
+    private static final String STOWED_REQUEST_ATTRIBS = "ssl.redirect.attrib.stowed";
+    private transient static Log log = LogFactory.getLog(RequestUtil.class);
+
+    /**
+     * Creates query String from request body parameters
+     */
+    public static String getRequestParameters(HttpServletRequest aRequest)
+    {
+        // set the ALGORIGTHM as defined for the application
+        //ALGORITHM = (String) aRequest.getAttribute(Constants.ENC_ALGORITHM);
+        Map m = aRequest.getParameterMap();
+        return createQueryStringFromMap(m, "&").toString();
+    }
+
+    /**
+     * Builds a query string from a given map of parameters
+     * 
+     * @param m
+     *            A map of parameters
+     * @param ampersand
+     *            String to use for ampersands (e.g. "&" or "&amp;" )
+     * 
+     * @return query string (with no leading "?")
+     */
+    public static StringBuffer createQueryStringFromMap(Map m, String ampersand)
+    {
+        StringBuffer aReturn = new StringBuffer("");
+        Set aEntryS = m.entrySet();
+        Iterator aEntryI = aEntryS.iterator();
+        while (aEntryI.hasNext())
+        {
+            Map.Entry aEntry = (Map.Entry) aEntryI.next();
+            Object o = aEntry.getValue();
+            if (o == null)
+            {
+                append(aEntry.getKey(), "", aReturn, ampersand);
+            }
+            else if (o instanceof String)
+            {
+                append(aEntry.getKey(), o, aReturn, ampersand);
+            }
+            else if (o instanceof String[])
+            {
+                String[] aValues = (String[]) o;
+                for (int i = 0; i < aValues.length; i++)
+                {
+                    append(aEntry.getKey(), aValues[i], aReturn, ampersand);
+                }
+            }
+            else
+            {
+                append(aEntry.getKey(), o, aReturn, ampersand);
+            }
+        }
+        return aReturn;
+    }
+
+    /**
+     * Appends new key and value pair to query string
+     * 
+     * @param key
+     *            parameter name
+     * @param value
+     *            value of parameter
+     * @param queryString
+     *            existing query string
+     * @param ampersand
+     *            string to use for ampersand (e.g. "&" or "&amp;")
+     * 
+     * @return query string (with no leading "?")
+     */
+    private static StringBuffer append(Object key, Object value,
+                    StringBuffer queryString, String ampersand)
+    {
+        if (queryString.length() > 0)
+        {
+            queryString.append(ampersand);
+        }
+        TagUtils tagUtils = TagUtils.getInstance();
+        // Use encodeURL from Struts' RequestUtils class - it's JDK 1.3 and 1.4
+        // compliant
+        queryString.append(tagUtils.encodeURL(key.toString()));
+        queryString.append("=");
+        queryString.append(tagUtils.encodeURL(value.toString()));
+        return queryString;
+    }
+
+    /**
+     * Stores request attributes in session
+     * 
+     * @param aRequest
+     *            the current request
+     */
+    public static void stowRequestAttributes(HttpServletRequest aRequest)
+    {
+        if (aRequest.getSession().getAttribute(STOWED_REQUEST_ATTRIBS) != null)
+        {
+            return;
+        }
+        Enumeration e = aRequest.getAttributeNames();
+        Map map = new HashMap();
+        while (e.hasMoreElements())
+        {
+            String name = (String) e.nextElement();
+            map.put(name, aRequest.getAttribute(name));
+        }
+        aRequest.getSession().setAttribute(STOWED_REQUEST_ATTRIBS, map);
+    }
+
+    /**
+     * Returns request attributes from session to request
+     * 
+     * @param aRequest
+     *            DOCUMENT ME!
+     */
+    public static void reclaimRequestAttributes(HttpServletRequest aRequest)
+    {
+        Map map = (Map) aRequest.getSession().getAttribute(
+                        STOWED_REQUEST_ATTRIBS);
+        if (map == null)
+        {
+            return;
+        }
+        Iterator itr = map.keySet().iterator();
+        while (itr.hasNext())
+        {
+            String name = (String) itr.next();
+            aRequest.setAttribute(name, map.get(name));
+        }
+        aRequest.getSession().removeAttribute(STOWED_REQUEST_ATTRIBS);
+    }
+
+    /**
+     * Convenience method to set a cookie
+     * 
+     * @param response
+     * @param name
+     * @param value
+     * @param path
+     */
+    public static void setCookie(HttpServletResponse response, String name,
+                    String value, String path)
+    {
+        if (log.isDebugEnabled())
+        {
+            log.debug("Setting cookie '" + name + "' on path '" + path + "'");
+        }
+        Cookie cookie = new Cookie(name, value);
+        cookie.setSecure(false);
+        // if path is nothing, use "/" so remember me will work 
+        // when installed as root app
+        cookie.setPath((path.length() == 0) ? "/" : path);
+        cookie.setMaxAge(3600 * 24 * 30); // 30 days
+        response.addCookie(cookie);
+    }
+
+    /**
+     * Convenience method to get a cookie by name
+     * 
+     * @param request
+     *            the current request
+     * @param name
+     *            the name of the cookie to find
+     * 
+     * @return the cookie (if found), null if not found
+     */
+    public static Cookie getCookie(HttpServletRequest request, String name)
+    {
+        Cookie[] cookies = request.getCookies();
+        Cookie returnCookie = null;
+        if (cookies == null)
+        {
+            return returnCookie;
+        }
+        for (int i = 0; i < cookies.length; i++)
+        {
+            Cookie thisCookie = cookies[i];
+            if (thisCookie.getName().equals(name))
+            {
+                // cookies with no value do me no good!
+                if (!thisCookie.getValue().equals(""))
+                {
+                    returnCookie = thisCookie;
+                    break;
+                }
+            }
+        }
+        return returnCookie;
+    }
+
+    /**
+     * Convenience method for deleting a cookie by name
+     * 
+     * @param response
+     *            the current web response
+     * @param cookie
+     *            the cookie to delete
+     * @param path
+     *            the path on which the cookie was set (i.e. /appfuse)
+     */
+    public static void deleteCookie(HttpServletResponse response,
+                    Cookie cookie, String path)
+    {
+        if (cookie != null)
+        {
+            // Delete the cookie by setting its maximum age to zero
+            cookie.setMaxAge(0);
+            cookie.setPath(path);
+            response.addCookie(cookie);
+        }
+    }
+
+    /**
+     * Convenience method to get the application's URL based on request
+     * variables.
+     */
+    public static String getAppURL(HttpServletRequest request)
+    {
+        StringBuffer url = new StringBuffer();
+        int port = request.getServerPort();
+        if (port < 0)
+        {
+            port = 80; // Work around java.net.URL bug
+        }
+        String scheme = request.getScheme();
+        url.append(scheme);
+        url.append("://");
+        url.append(request.getServerName());
+        if ((scheme.equals("http") && (port != 80))
+                        || (scheme.equals("https") && (port != 443)))
+        {
+            url.append(':');
+            url.append(port);
+        }
+        return url.toString();
+    }
+}
\ No newline at end of file

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/util/SslUtil.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/util/SslUtil.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/util/SslUtil.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/util/SslUtil.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,131 @@
+package org.roller.presentation.util;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+
+import org.roller.config.RollerConfig;
+
+/**
+ * SslUtil utility class Good ol' copy-n-paste from  <a
+ * href="http://www.javaworld.com/javaworld/jw-02-2002/ssl/utilityclass.txt">
+ * http://www.javaworld.com/javaworld/jw-02-2002/ssl/utilityclass.txt</a>
+ * which is referenced in the following article: <a
+ * href="http://www.javaworld.com/javaworld/jw-02-2002/jw-0215-ssl.html">
+ * http://www.javaworld.com/javaworld/jw-02-2002/jw-0215-ssl.html</a>
+ */
+public class SslUtil {
+    //~ Static fields/initializers =============================================
+
+    public static final String HTTP = "http";
+    public static final String HTTPS = "https";
+    public static final String HTTP_PORT_PARAM = "listenPort_http";
+    public static final String HTTPS_PORT_PARAM = "listenPort_https";
+    private static String HTTP_PORT = null;
+    private static String HTTPS_PORT = null;
+    public static final String STD_HTTP_PORT = "80";
+    public static final String STD_HTTPS_PORT = "443";
+
+    //~ Methods ================================================================
+
+    public static String getRedirectString(HttpServletRequest request,
+                                           ServletContext ctx, boolean isSecure) {
+        // get the port numbers from the application context
+        HTTP_PORT = RollerConfig.getProperty("securelogin.http.port");
+        HTTPS_PORT = RollerConfig.getProperty("securelogin.https.port");
+
+        // get the scheme we want to use for this page and
+        // get the scheme used in this request
+        String desiredScheme = isSecure ? HTTPS : HTTP;
+        String usingScheme = request.getScheme();
+
+        // Determine the port number we want to use
+        // and the port number we used in this request
+        String desiredPort = isSecure ? HTTPS_PORT : HTTP_PORT;
+        String usingPort = String.valueOf(request.getServerPort());
+
+        String urlString = null;
+
+        // Must also check ports, because of IE multiple redirect problem
+        if (!desiredScheme.equals(usingScheme) ||
+                !desiredPort.equals(usingPort)) {
+            urlString =
+                buildNewUrlString(request, desiredScheme, usingScheme,
+                                  desiredPort, usingPort);
+
+            // Temporarily store attributes in session
+            RequestUtil.stowRequestAttributes(request);
+        } else {
+            // Retrieve attributes from session
+            RequestUtil.reclaimRequestAttributes(request);
+        }
+
+        return urlString;
+    }
+
+    /**
+     * Builds the URL that we will redirect to
+     *
+     * @param request DOCUMENT ME!
+     * @param desiredScheme DOCUMENT ME!
+     * @param usingScheme DOCUMENT ME!
+     * @param desiredPort DOCUMENT ME!
+     * @param usingPort DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    private static String buildNewUrlString(HttpServletRequest request,
+                                            String desiredScheme,
+                                            String usingScheme,
+                                            String desiredPort, String usingPort) {
+        StringBuffer url = request.getRequestURL();
+
+        url.replace(0, usingScheme.length(), desiredScheme);
+
+        // Find the port used within the URL string
+        int startIndex = url.toString().indexOf(usingPort);
+
+        if (startIndex == -1) { // Port not found in URL
+
+            if ((!(STD_HTTPS_PORT.equals(desiredPort) &&
+                    HTTPS.equals(desiredScheme))) &&
+                    (!(STD_HTTP_PORT.equals(desiredPort) &&
+                    HTTP.equals(desiredScheme)))) {
+                startIndex =
+                    url.toString().indexOf("/",
+                                           url.toString().indexOf("/",
+                                                                  url.toString()
+                                                                     .indexOf("/") +
+                                                                  1) + 1);
+                url.insert(startIndex, ":" + desiredPort);
+            }
+        } else { // Port found in URL
+
+            if ((STD_HTTPS_PORT.equals(desiredPort) &&
+                    HTTPS.equals(desiredScheme)) ||
+                    (STD_HTTP_PORT.equals(desiredPort) &&
+                    HTTP.equals(desiredScheme))) {
+                url.delete(startIndex - 1, startIndex + usingPort.length());
+            } else { // desired port is not a default port
+
+                // Replace requested port with desired port number in URL string
+                url.replace(startIndex, startIndex + usingPort.length(),
+                            desiredPort);
+            }
+        }
+
+        // add query string, if any
+        String queryString = request.getQueryString();
+
+        if ((queryString != null) && (queryString.length() != 0)) {
+            url.append("?" + queryString);
+        } else {
+            queryString = RequestUtil.getRequestParameters(request);
+
+            if ((queryString != null) && (queryString.length() != 0)) {
+                url.append("?" + queryString);
+            }
+        }
+
+        return url.toString();
+    }
+}

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/util/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/util/package.html?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/util/package.html (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/util/package.html Fri Oct 21 14:27:36 2005
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title></title>
+</head>
+<body>
+Presentation layer utilities.
+
+</body>
+</html>

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/BasePageServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/BasePageServlet.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/BasePageServlet.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/BasePageServlet.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,225 @@
+package org.roller.presentation.velocity;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Map;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+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.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.servlet.VelocityServlet;
+import org.roller.model.RollerFactory;
+import org.roller.model.UserManager;
+import org.roller.pojos.UserData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.RollerRequest;
+
+/**
+ * Base Servlet for Servlets that render user page templates. Loads the
+ * Velocity context using the ContextLoader and runs the page template
+ * selected by the request.
+ *
+ * @author llavandowska
+ * @author David M Johnson
+ * @author Allen Gilliland
+ */
+public abstract class BasePageServlet extends VelocityServlet {
+    
+    private static Log mLogger =
+            LogFactory.getFactory().getInstance(BasePageServlet.class);
+    
+    
+    /**
+     * Sets servletContext for WebappResourceLoader.
+     */
+    public void init( ServletConfig config )
+        throws ServletException {
+        
+        super.init( config );
+        WebappResourceLoader.setServletContext( getServletContext() );
+    }
+    
+    
+    public Template handleRequest( HttpServletRequest request,
+            HttpServletResponse response,
+            Context ctx ) throws Exception {
+        
+        Template outty = null;
+        Exception pageException = null;
+        
+        try {
+            PageContext pageContext =
+                    JspFactory.getDefaultFactory().getPageContext(
+                    this, request, response,"", true, 8192, true);
+            // Needed to init request attributes, etc.
+            RollerRequest rreq = RollerRequest.getRollerRequest(pageContext);
+            UserManager userMgr = RollerFactory.getRoller().getUserManager();
+            
+            WebsiteData website = null;
+            if (request.getAttribute(RollerRequest.OWNING_USER) != null) {
+                UserData user = (UserData)
+                    request.getAttribute(RollerRequest.OWNING_USER);
+                website = userMgr.getWebsite(user.getUserName());
+            } else {
+                website = rreq.getWebsite();
+            }
+            
+            org.roller.pojos.Template page = null;
+            
+            // If request specified the page, then go with that
+            if (rreq.getPage() != null &&
+                    rreq.getRequest().getAttribute(RollerRequest.OWNING_USER) == null) {
+                page = rreq.getPage();
+                
+                // If page not available from request, then use website's default
+            } else if (website != null) {
+                page = website.getDefaultPage();
+                rreq.setPage(page);
+            }
+            
+            // Still no page ID, then we have a problem
+            if ( page == null ) {
+                throw new ResourceNotFoundException("Page not found");
+            }
+
+            // this sets up the page we want to render
+            outty = prepareForPageExecution(ctx, rreq, response, page);
+            
+            // if there is a decorator template then apply it
+            if (website != null) {
+                // parse/merge Page template
+                StringWriter sw = new StringWriter();
+                outty.merge(ctx, sw);
+                ctx.put("decorator_body", sw.toString());
+                
+                // replace outty with decorator Template
+                outty = findDecorator(website, (String) ctx.get("decorator"));
+            }
+            
+        } 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);
+        }
+        
+        return outty;
+    }
+    
+    
+    /**
+     * Prepare the requested page for execution by setting content type
+     * and populating velocity context.
+     */
+    protected Template prepareForPageExecution(Context ctx,
+            RollerRequest rreq,
+            HttpServletResponse response,
+            org.roller.pojos.Template page) throws Exception {
+        
+        Template outty = null;
+        
+        // if page has an extension - use that to set the contentType
+        String pageLink = page.getLink();
+        String mimeType = getServletConfig().getServletContext().getMimeType(pageLink);
+        if(mimeType != null) {
+            // we found a match ... set the content type
+            response.setContentType(mimeType);
+        }
+        
+        // Made it this far, populate the Context
+        ContextLoader.setupContext( ctx, rreq, response );
+        
+        return getTemplate( page.getId(), "UTF-8" );
+    }
+    
+    
+    /**
+     * Load the decorator template and apply it.  If there is no user specified
+     * decorator then the default decorator is applied.
+     */
+    protected Template findDecorator(WebsiteData website, String decorator_name)
+        throws Exception {
+        
+        Template decorator = null;
+        org.roller.pojos.Template decorator_template = null;
+        
+        // check for user-specified decorator
+        if (decorator_name != null) {
+            decorator_template = website.getPageByName(decorator_name);
+        }
+        
+        // if no user-specified decorator try default page-name
+        if (decorator_template == null) {
+            decorator_template = website.getPageByName("_decorator");
+        }
+        
+        // try loading Template
+        if (decorator_template != null) {
+            try {
+                decorator = getTemplate(decorator_template.getId(), "UTF-8");
+            } catch (Exception e) {
+                // it may not exist, so this is okay
+            }
+        }
+        
+        // couldn't find Template, load default "no-op" decorator
+        if (decorator == null) {
+            decorator = getTemplate("/themes/noop_decorator.vm", "UTF-8");
+        }
+        
+        return decorator;
+    }
+    
+    
+    /**
+     * Handle error in Velocity processing.
+     */
+    protected void error( HttpServletRequest req, HttpServletResponse res,
+            Exception e) throws ServletException, IOException {
+        mLogger.warn("ERROR in VelocityServlet",e);
+    }
+    
+    /**
+     * Override to prevent Velocity from putting "req" and "res" into the context.
+     * Allowing users access to the underlying Servlet objects is a security risk.
+     * If need access to request parameters, use $requestParameters.
+     */
+    protected Context createContext(
+            HttpServletRequest req,
+            HttpServletResponse res) {
+        
+        VelocityContext context = new VelocityContext();
+        context.put(REQUEST, new RequestWrapper(req.getParameterMap()));
+        return context;
+        
+    }
+    
+    /** Provide access to request params only, not actual request */
+    public static class RequestWrapper {
+        Map params = null;
+        public RequestWrapper(Map params) {
+            this.params = params;
+        }
+        public String getParameter(String key) {
+            String ret = null;
+            String[] array = (String[])params.get(key);
+            if (array != null && array.length > 0) {
+                ret = array[0];
+            }
+            return ret;
+        }
+    }
+}

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/CommentAuthenticator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/CommentAuthenticator.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/CommentAuthenticator.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/velocity/CommentAuthenticator.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,38 @@
+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;
+
+/**
+ * Interface for comment authentication plugin.
+ * @author David M Johnson
+ */
+public interface CommentAuthenticator
+{
+    /**
+     * Plugin should write out HTML for the form fields and other UI elements
+     * needed inside the Roller comment form. Called when HTML form is being 
+     * displayed by Velocity template (see comments.vm).
+     *
+     * @param context Plugin can access objects in context of calling page.
+     * @param request Plugin can access request parameters
+     * @param response Plugin should write to response
+     */
+    public String getHtml(
+                        Context context,
+                        HttpServletRequest request, 
+                        HttpServletResponse response);
+    /**
+     * Plugin should return true only if comment passes authentication test.
+     * Called when a comment is posted, not called when a comment is previewed.
+     *
+     * @param comment Comment data that was posted 
+     * @param request Plugin can access request parameters
+     * @return True if comment passes authentication test
+     */
+    public boolean authenticate(
+                        CommentData comment,
+                        HttpServletRequest request);
+}