roller-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From snoopd...@apache.org
Subject svn commit: r189695 [30/67] - 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/ contrib/plugins/src/org/roller/presentation/velocity/plugins/topictag/ custom/ custom/src/ custom/web/ docs/ docs/images/ docs/installguide/ docs/installguide/old/ docs/userguide/ docs/userguide/images/ docs/userguide/old/ metadata/ metadata/database/ metadata/database/hibernate/ metadata/xdoclet/ nbproject/ personal/ personal/eclipse/ personal/testing/ sandbox/ sandbox/planetroller/ sandbox/planetroller/metadata/ sandbox/planetroller/metadata/database/ sandbox/planetroller/src/ sandbox/planetroller/src/org/ sandbox/planetroller/src/org/roller/ sandbox/planetroller/src/org/roller/tools/ sandbox/planetroller/src/org/roller/tools/planet/ sandbox/planetroller/templates/ sandbox/planetroller/test/ sandbox/planetroller/test/org/ sandbox/planetroller/test/org/roller/ sandbox/planetroller/test/org/roller/model/ sandbox/planetroller/test/org/roller/tools/ sandbox/planetroller/test/org/roller/tools/planet/ sandbox/planetroller/testdata/ sandbox/planetroller/testdata/cache/ sandbox/planetroller/testdata/output/ sandbox/standalone/ sandbox/standalone/jspwiki/ sandbox/standalone/jspwiki/default/ sandbox/standalone/jspwiki/default/images/ sandbox/standalone/lib/ sandbox/standalone/src/ sandbox/standalone/src/org/ sandbox/standalone/src/org/roller/ sandbox/standalone/src/org/roller/jspwiki/ sandbox/standalone/src/org/roller/tomcat/ sandbox/standalone/src/org/roller/util/ sandbox/standalone/tests/ sandbox/standalone/tests/org/ sandbox/standalone/tests/org/roller/ sandbox/standalone/tests/org/roller/util/ sandbox/standalone/tomcat/ src/ src/org/ src/org/roller/ src/org/roller/business/ src/org/roller/business/hibernate/ src/org/roller/business/search/ src/org/roller/business/search/operations/ src/org/roller/business/utils/ src/org/roller/config/ src/org/roller/config/runtime/ src/org/roller/model/ src/org/roller/pojos/ src/org/roller/presentation/ src/org/roller/presentation/atomapi/ 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/pings/ src/org/roller/presentation/planet/ src/org/roller/presentation/tags/ src/org/roller/presentation/tags/calendar/ src/org/roller/presentation/tags/menu/ src/org/roller/presentation/util/ 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/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/ src/org/roller/util/rome/ tests/ tests/org/ tests/org/roller/ tests/org/roller/ant/ tests/org/roller/business/ tests/org/roller/presentation/ tests/org/roller/presentation/atomapi/ tests/org/roller/presentation/bookmarks/ tests/org/roller/presentation/filters/ 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/weblog/ tests/org/roller/presentation/xmlrpc/ tests/org/roller/util/ tests/org/roller/util/rome/ tools/ tools/buildtime/ tools/buildtime/ant-1.6.2/ tools/buildtime/findbugs/ tools/buildtime/findbugs/lib/ tools/buildtime/findbugs/plugin/ tools/buildtime/mockrunner-0.3/ tools/buildtime/mockrunner-0.3/lib/ tools/buildtime/mockrunner-0.35/ tools/buildtime/mockrunner-0.35/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.2.4/ tools/struts-1.2.4/lib/ web/ web/WEB-INF/ web/WEB-INF/classes/ web/WEB-INF/classes/flavors/ web/WEB-INF/classes/themes/ web/bookmarks/ web/editor/ web/editor/images/ web/images/ web/images/editor/ web/images/midas/ web/images/preview/ web/images/smileys/ web/planet/ 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/brushedmetal/ web/themes/brushedmetal/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/movablemanila/ web/themes/movablemanila/images/ 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 Thu, 09 Jun 2005 03:19:20 GMT
Added: incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/BookmarkSaveAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/BookmarkSaveAction.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/BookmarkSaveAction.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/BookmarkSaveAction.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,78 @@
+/*
+ * Created on Oct 21, 2003
+ */
+package org.roller.presentation.bookmarks.actions;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionError;
+import org.apache.struts.action.ActionErrors;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.roller.RollerPermissionsException;
+import org.roller.model.BookmarkManager;
+import org.roller.pojos.BookmarkData;
+import org.roller.pojos.FolderData;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.bookmarks.formbeans.BookmarkFormEx;
+
+/**
+ * @struts.action path="/editor/bookmarkSave" name="bookmarkFormEx"
+ *    validate="true" input="/editor/bookmarkEdit.do"
+ * @struts.action-forward name="Bookmarks" path="/editor/bookmarks.do?method=selectFolder"
+ * 
+ * @author Dave Johnson
+ */
+public class BookmarkSaveAction extends Action
+{
+    public ActionForward execute(
+        ActionMapping       mapping,
+        ActionForm          actionForm,
+        HttpServletRequest  request,
+        HttpServletResponse response)
+        throws Exception
+    {
+        ActionForward forward = mapping.findForward("Bookmarks");
+        try
+        {
+            BookmarkFormEx form = (BookmarkFormEx)actionForm;
+            RollerRequest rreq = RollerRequest.getRollerRequest(request);
+            BookmarkManager bmgr = rreq.getRoller().getBookmarkManager();
+            
+            BookmarkData bd = null;
+            if (null != form.getId() && !form.getId().trim().equals("")) 
+            {
+                bd = bmgr.retrieveBookmark(form.getId());
+                bd.save(); // should throw if save not permitted
+            }
+            else 
+            {
+                bd = bmgr.createBookmark();
+                
+                // Existing bookmarks already have folders, but this is a new one.
+                FolderData fd = bmgr.retrieveFolder(
+                    request.getParameter(RollerRequest.FOLDERID_KEY));
+                bd.setFolder(fd);
+            }
+            form.copyTo(bd, request.getLocale());
+            bd.save();
+            rreq.getRoller().commit();
+            
+            request.setAttribute(
+                RollerRequest.FOLDERID_KEY,bd.getFolder().getId());  
+        }
+        catch (RollerPermissionsException e)
+        {
+            ActionErrors errors = new ActionErrors();
+            errors.add(null, new ActionError("error.permissions.deniedSave"));
+            saveErrors(request, errors);
+            forward = mapping.findForward("access-denied");
+        }
+        return forward;
+        
+    }
+
+}

Added: incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/BookmarksAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/BookmarksAction.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/BookmarksAction.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/BookmarksAction.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,301 @@
+/*
+ * Created on Oct 21, 2003
+ */
+package org.roller.presentation.bookmarks.actions;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.TreeSet;
+
+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.action.ActionError;
+import org.apache.struts.action.ActionErrors;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.action.ActionMessage;
+import org.apache.struts.action.ActionMessages;
+import org.apache.struts.actions.DispatchAction;
+import org.roller.RollerException;
+import org.roller.model.BookmarkManager;
+import org.roller.pojos.BookmarkData;
+import org.roller.pojos.FolderData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.bookmarks.formbeans.BookmarksForm;
+
+/**
+ * Actions that are initiated from the BookmarksForm.
+ *
+ * @struts.action name="bookmarksForm" path="/editor/bookmarks" parameter="method"
+ * @struts.action-forward name="BookmarksForm" path="/bookmarks/BookmarksForm.jsp"
+ *
+ * @author Dave Johnson
+ */
+public class BookmarksAction extends DispatchAction
+{
+    private static Log mLogger =
+        LogFactory.getFactory().getInstance(BookmarksAction.class);
+
+    /**
+     * Present the BookmarksForm loaded with folder specified by request.
+     * @param mapping Action mapping.
+     * @param actionForm Form bean.
+     * @param request Request.
+     * @param response Response.
+     * @return Forward to BookmarksForm or access-denied.
+     * @throws RollerException
+     */
+    public ActionForward selectFolder(
+        ActionMapping       mapping,
+        ActionForm          actionForm,
+        HttpServletRequest  request,
+        HttpServletResponse response)
+        throws RollerException
+    {
+        RollerRequest rreq = RollerRequest.getRollerRequest(request);
+        if (rreq.isUserAuthorizedToEdit())
+        {
+            addModelObjects(request, (BookmarksForm)actionForm);
+            return mapping.findForward("BookmarksForm");
+        }
+        else
+        {
+            return mapping.findForward("access-denied");
+        }
+    }
+
+    /**
+     * Delete folders and bookmarks indicated by BookmarksForm bean.
+     * @param mapping Action mapping.
+     * @param actionForm Form bean.
+     * @param request Request.
+     * @param response Response.
+     * @return Forward to BookmarksForm or access-denied.
+     * @throws RollerException
+     */
+    public ActionForward deleteSelected(
+        ActionMapping       mapping,
+        ActionForm          actionForm,
+        HttpServletRequest  request,
+        HttpServletResponse response)
+        throws RollerException
+    {
+        RollerRequest rreq = RollerRequest.getRollerRequest(request);
+        if (rreq.isUserAuthorizedToEdit())
+        {
+            BookmarkManager bmgr = rreq.getRoller().getBookmarkManager();
+            BookmarksForm form = (BookmarksForm)actionForm;
+
+            mLogger.debug("Deleting folders and bookmarks.");
+
+            String folders[] = form.getSelectedFolders();
+            if (null != folders)
+            {
+                for (int i = 0; i < folders.length; i++)
+                {
+                    FolderData fd = bmgr.retrieveFolder(folders[i]);
+                    fd.remove(); // removes child folders and bookmarks too
+                }
+            }
+
+            String bookmarks[] = form.getSelectedBookmarks();
+            if (null != bookmarks)
+            {
+                for (int j = 0; j < bookmarks.length; j++)
+                {
+                    bmgr.removeBookmark(bookmarks[j]);
+                }
+            }
+            rreq.getRoller().commit();
+
+            addModelObjects(request, (BookmarksForm)actionForm);
+            return mapping.findForward("BookmarksForm");
+        }
+        else
+        {
+            return mapping.findForward("access-denied");
+        }
+    }
+
+    /**
+     * Move folders and bookmarks indicated by BookmarksForm bean.
+     * @param mapping Action mapping.
+     * @param actionForm  Form bean.
+     * @param request Request.
+     * @param response Response.
+     * @return Forward to BookmarksForm or access-denied.
+     * @throws RollerException
+     */
+    public ActionForward moveSelected(
+        ActionMapping       mapping,
+        ActionForm          actionForm,
+        HttpServletRequest  request,
+        HttpServletResponse response)
+        throws RollerException
+    {
+        ActionMessages messages = new ActionMessages();
+        ActionForward forward = mapping.findForward("BookmarksForm");
+        RollerRequest rreq = RollerRequest.getRollerRequest(request);
+        if (rreq.isUserAuthorizedToEdit())
+        {
+            try 
+            {
+                BookmarkManager bmgr = rreq.getRoller().getBookmarkManager();
+                BookmarksForm form = (BookmarksForm)actionForm;
+    
+                mLogger.debug("Moving folders and bookmarks to folder, id="
+                    + form.getMoveToFolderId());
+    
+                // Move subfolders to new folder.
+                String folders[] = form.getSelectedFolders();
+                FolderData parent = bmgr.retrieveFolder(form.getMoveToFolderId());
+                if (null != folders)
+                {
+                    for (int i = 0; i < folders.length; i++)
+                    {
+                        FolderData fd = bmgr.retrieveFolder(folders[i]);
+    
+                        // Don't move folder into itself.
+                        if (    !fd.getId().equals(parent.getId())
+                             && !parent.descendentOf(fd))
+                        {
+                            fd.setParent(parent);
+                            fd.save();
+                        }
+                        else 
+                        {
+                            messages.add(null, new ActionMessage(
+                                "bookmarksForm.warn.notMoving",fd.getName()));
+                        }
+                    }
+                }
+    
+                // Move bookmarks.
+                String bookmarks[] = form.getSelectedBookmarks();
+                if (null != bookmarks)
+                {
+                    for (int j = 0; j < bookmarks.length; j++)
+                    {
+                        BookmarkData bd = bmgr.retrieveBookmark(bookmarks[j]);
+                        bd.setFolder(parent);
+                        bd.save();
+                    }
+                }
+                rreq.getRoller().commit();
+    
+                addModelObjects(request, (BookmarksForm)actionForm);
+                saveMessages(request, messages);
+            }
+            catch (RollerException e)
+            {
+                ActionErrors errors = new ActionErrors();
+                errors.add(null, new ActionError("bookmarksForm.error.move"));
+                saveErrors(request, errors);       
+            }
+        }
+        else
+        {
+            forward = mapping.findForward("access-denied");
+        }
+        return forward;
+    }
+
+    /**
+     * Load model objects for display in BookmarksForm.
+     * @param request
+     * @throws RollerException
+     */
+    private void addModelObjects(HttpServletRequest request, BookmarksForm form)
+        throws RollerException
+    {
+        RollerRequest rreq = RollerRequest.getRollerRequest(request);
+        WebsiteData wd = rreq.getWebsite();
+        BookmarkManager bmgr = rreq.getRoller().getBookmarkManager();
+
+        TreeSet allFolders = new TreeSet(new FolderPathComparator());
+
+        // Find folderid wherever it may be
+        String folderId = (String)request.getAttribute(RollerRequest.FOLDERID_KEY);
+        if (null == folderId)
+        {
+            folderId = request.getParameter(RollerRequest.FOLDERID_KEY);
+        }
+        if (null == folderId)
+        {
+            folderId = form.getFolderId();
+        }
+
+        FolderData folder = null;
+        if (null == folderId || folderId.equals("null"))
+        {
+            folder = bmgr.getRootFolder(wd);
+        }
+        else
+        {
+            folder = bmgr.retrieveFolder(folderId);
+        }
+        form.setFolderId(folder.getId());
+
+        request.setAttribute("folder", folder);
+        request.setAttribute("folders", folder.getFolders());
+        request.setAttribute("bookmarks", folder.getBookmarks());
+
+        if (null != folder.getParent())
+        {
+            LinkedList folderPath = new LinkedList();
+            folderPath.add(0, folder);
+            FolderData parent = folder.getParent();
+            while (parent != null)
+            {
+                folderPath.add(0, parent);
+                parent = parent.getParent();
+            }
+            request.setAttribute("folderPath", folderPath);
+
+            request.setAttribute(
+                RollerRequest.PARENTID_KEY, folder.getParent().getId());
+        }
+
+        // Build list of all folders, except for current one, sorted by path.
+        Iterator iter = bmgr.getAllFolders(wd).iterator();
+
+        // Build list of only children
+        //Iterator iter = folder.getFolders().iterator();
+
+        //int max = 20, count = 0;
+        while (iter.hasNext()) // && count < max)
+        {
+            //count++;
+            FolderData fd = (FolderData) iter.next();
+            if (!fd.getId().equals(folderId))
+            {
+                allFolders.add(fd);
+            }
+        }
+        request.setAttribute("allFolders", allFolders);
+    }
+
+    private static final class FolderPathComparator implements Comparator
+    {
+        public int compare(Object o1, Object o2) {
+            FolderData f1 = (FolderData)o1;
+            FolderData f2 = (FolderData)o2;
+            int res = 0;
+            try
+            {
+                res = f1.getPath().compareTo(f2.getPath());
+            }
+            catch (RollerException e)
+            {
+                mLogger.error("ERROR: sorting folders");
+            }
+            return res;
+        }
+    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/FolderEditAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/FolderEditAction.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/FolderEditAction.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/FolderEditAction.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,73 @@
+/*
+ * Created on Oct 21, 2003
+ */
+package org.roller.presentation.bookmarks.actions;
+
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.roller.model.BookmarkManager;
+import org.roller.pojos.FolderData;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.bookmarks.formbeans.FolderFormEx;
+
+import java.util.LinkedList;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @struts.action path="/editor/folderEdit" name="folderFormEx" validate="false"
+ * @struts.action-forward name="FolderForm" path="/bookmarks/FolderForm.jsp"
+ * 
+ * @author Dave Johnson
+ */
+public class FolderEditAction extends Action
+{
+    public ActionForward execute(
+        ActionMapping       mapping,
+        ActionForm          actionForm,
+        HttpServletRequest  request,
+        HttpServletResponse response)
+        throws Exception
+    {
+        RollerRequest rreq = RollerRequest.getRollerRequest(request);
+        BookmarkManager bmgr = rreq.getRoller().getBookmarkManager();
+        FolderFormEx form = (FolderFormEx)actionForm;
+        
+        FolderData parentFolder = null;
+        if (null!=rreq.getFolder() && null==request.getParameter("correct")) 
+        {
+            // If request specifies folder and we are not correcting an 
+            // already submitted form then load that folder into the form.
+            request.setAttribute("state","edit"); 
+
+            FolderData fd = rreq.getFolder();
+            form.copyFrom(fd, request.getLocale());
+            parentFolder = fd.getParent();
+        }
+        else if (null != request.getParameter("correct"))
+        {
+            // We are correcting a previously submtted form.
+            request.setAttribute("state","correcting"); 
+            
+            String parentId = request.getParameter(RollerRequest.PARENTID_KEY);
+            parentFolder = bmgr.retrieveFolder(parentId);
+        }
+        else
+        {
+            // We are adding a new bookmark
+            request.setAttribute("state","add");
+            
+            String parentId = request.getParameter(RollerRequest.PARENTID_KEY);
+            parentFolder = bmgr.retrieveFolder(parentId);
+        }
+        
+        request.setAttribute(RollerRequest.PARENTID_KEY, parentFolder.getId());
+        request.setAttribute("parentFolder", parentFolder);
+        
+        return mapping.findForward("FolderForm");
+    }
+
+}

Added: incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/FolderSaveAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/FolderSaveAction.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/FolderSaveAction.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/FolderSaveAction.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,104 @@
+/*
+ * Created on Oct 21, 2003
+ */
+package org.roller.presentation.bookmarks.actions;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionError;
+import org.apache.struts.action.ActionErrors;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.roller.RollerException;
+import org.roller.RollerPermissionsException;
+import org.roller.model.BookmarkManager;
+import org.roller.pojos.FolderData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.bookmarks.formbeans.FolderFormEx;
+
+/**
+ * @struts.action path="/editor/folderSave" name="folderFormEx" 
+ *     validate="true" input="/editor/folderEdit.do"
+ * @struts.action-forward name="Bookmarks" path="/editor/bookmarks.do?method=selectFolder"
+ * 
+ * @author Dave Johnson
+ */
+public class FolderSaveAction extends Action
+{
+    public ActionForward execute(
+        ActionMapping       mapping,
+        ActionForm          actionForm,
+        HttpServletRequest  request,
+        HttpServletResponse response)
+        throws Exception
+    {
+        ActionForward forward = mapping.findForward("Bookmarks");
+        FolderFormEx form = (FolderFormEx)actionForm;
+        RollerRequest rreq = RollerRequest.getRollerRequest(request);
+        WebsiteData wd = rreq.getWebsite();
+        BookmarkManager bmgr = rreq.getRoller().getBookmarkManager();
+        
+        FolderData fd = null;
+        if (null != form.getId() && !form.getId().trim().equals("")) 
+        {
+            fd = bmgr.retrieveFolder(form.getId());
+            fd.save(); // should throw if save not permitted
+        }
+        else 
+        {
+            fd = bmgr.createFolder();
+        
+            String parentId = request.getParameter(RollerRequest.PARENTID_KEY);
+            FolderData parent = null;
+            if (null != parentId && !parentId.trim().equalsIgnoreCase("null"))
+            {
+                parent = bmgr.retrieveFolder(parentId);
+            }
+            else 
+            {
+                parent = bmgr.getRootFolder(wd);
+            }
+            fd.setParent(parent);
+            fd.setWebsite(wd);
+        }
+        
+        // Copy form values to object
+        form.copyTo(fd, request.getLocale());
+            
+        try 
+        {
+            // Store object and commit
+            fd.save();
+            rreq.getRoller().commit();
+        }
+        catch (RollerPermissionsException e)
+        {
+            ActionErrors errors = new ActionErrors();
+            errors.add(null, new ActionError("error.permissions.deniedSave"));
+            saveErrors(request, errors);
+            forward = mapping.findForward("access-denied");
+        }
+        catch (RollerException re)
+        {
+            rreq.getRoller().rollback();
+            ActionErrors errors = new ActionErrors();
+            String msg = (null != re.getRootCause())
+                ? re.getRootCause().toString()
+                : re.toString();
+            errors.add(ActionErrors.GLOBAL_ERROR, 
+               new ActionError("folderForm.save.exception", msg));
+            saveErrors(request,errors);            
+        }
+         
+        if (null != fd.getParent()) 
+        {
+            request.setAttribute(
+               RollerRequest.FOLDERID_KEY, fd.getParent().getId());
+        }         
+        return forward;
+    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/ImportBookmarksFormAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/ImportBookmarksFormAction.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/ImportBookmarksFormAction.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/ImportBookmarksFormAction.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,154 @@
+
+package org.roller.presentation.bookmarks.actions;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionError;
+import org.apache.struts.action.ActionErrors;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.upload.FormFile;
+import org.roller.model.BookmarkManager;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.bookmarks.formbeans.FolderFormEx;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+/////////////////////////////////////////////////////////////////////////////
+/**
+ * @struts.action name="folderFormEx" path="/editor/importBookmarks" 
+ *  scope="request" input="/bookmarks/import.jsp" validate="false"
+ * 
+ * @struts.action-forward name="importBookmarks.page" path="/bookmarks/import.jsp"
+ * 
+ * TODO Should import into folder with same name as imported file
+ */
+public final class ImportBookmarksFormAction extends Action
+{
+    private static Log mLogger = 
+        LogFactory.getFactory().getInstance(RollerRequest.class);
+
+	/** 
+     * Request to import bookmarks 
+     */
+	public ActionForward execute(
+		ActionMapping 		mapping,
+		ActionForm 			actionForm,
+		HttpServletRequest 	request,
+		HttpServletResponse response)
+		throws IOException, ServletException 
+	{
+        ActionErrors errors = new ActionErrors();
+	    FolderFormEx theForm = (FolderFormEx)actionForm;
+		ActionForward fwd = mapping.findForward("importBookmarks.page");
+	    if ( theForm.getBookmarksFile() != null )
+        {
+            //this line is here for when the input page is upload-utf8.jsp,
+            //it sets the correct character encoding for the response
+            String encoding = request.getCharacterEncoding();
+            if ((encoding != null) && (encoding.equalsIgnoreCase("utf-8")))
+            {
+                response.setContentType("text/html; charset=utf-8");
+            }
+
+            boolean writeFile = false; //theForm.getWriteFile();
+
+            //retrieve the file representation
+            FormFile file = theForm.getBookmarksFile();
+        /*
+            //retrieve the file name
+            String fileName= file.getFileName();
+
+            //retrieve the content type
+            String contentType = file.getContentType();
+
+            //retrieve the file size
+            String size = (file.getFileSize() + " bytes");
+        */
+            String data = null;
+
+            InputStream stream = null;
+            try 
+            {
+                //retrieve the file data
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                stream = file.getInputStream();
+                if (!writeFile) 
+                {
+                    //only write files out that are less than 1MB
+                    if (file.getFileSize() < (4*1024000)) {
+
+                        byte[] buffer = new byte[8192];
+                        int bytesRead = 0;
+                        while ((bytesRead=stream.read(buffer,0,8192)) != -1) {
+                            baos.write(buffer, 0, bytesRead);
+                        }
+                        data = new String(baos.toByteArray());
+
+                        // Use Roller BookmarkManager to import bookmarks
+                        RollerRequest rreq = 
+                            RollerRequest.getRollerRequest(request);
+                        BookmarkManager bm = 
+                            rreq.getRoller().getBookmarkManager();    
+                        bm.importBookmarks(rreq.getWebsite(), "unfiled", data);
+                        
+                        rreq.getRoller().commit();
+                    }
+                    else 
+                    {
+                        data = "The file is greater than 4MB, " 
+                            +" and has not been written to stream." 
+                            +" File Size: "+file.getFileSize()+" bytes. " 
+                            +" This is a limitation of this particular "
+                            +" web application, hard-coded in "
+                            +" org.apache.struts.webapp.upload.UploadAction";
+                    }
+                }
+                else 
+                {
+                    //write the file to the file specified
+                    /*OutputStream bos = 
+                        new FileOutputStream(theForm.getFilePath());
+                    int bytesRead = 0;
+                    byte[] buffer = new byte[8192];
+                    while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
+                        bos.write(buffer, 0, bytesRead);
+                    }
+                    bos.close();
+                    data = "The file has been written to \"" 
+                        + theForm.getFilePath() + "\"";
+                    */
+                }
+            }
+            catch (Exception e) 
+            {
+            	errors.add(ActionErrors.GLOBAL_ERROR,
+				    new ActionError("error.importing.bookmarks",e.toString()));
+			    saveErrors(request,errors);
+                mLogger.error("ERROR: importing bookmarks",e);
+            }
+            finally 
+            {
+                if ( stream!=null )
+                {
+                    try { stream.close(); } 
+                    catch (Exception e) { mLogger.error("Closing stream",e); };
+                }
+            }
+
+            //destroy the temporary file created
+            file.destroy();
+        }
+		return fwd; 
+	}
+}
+

Added: incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/package.html?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/package.html (added)
+++ incubator/roller/trunk/src/org/roller/presentation/bookmarks/actions/package.html Wed Jun  8 20:18:46 2005
@@ -0,0 +1,9 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title></title>
+</head>
+<body>
+Actions for bookmarks forms.<br>
+</body>
+</html>

Added: incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/BookmarkFormEx.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/BookmarkFormEx.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/BookmarkFormEx.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/BookmarkFormEx.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,60 @@
+/*
+ * Created on Apr 8, 2003
+ */
+package org.roller.presentation.bookmarks.formbeans;
+
+import org.roller.RollerException;
+import org.roller.pojos.BookmarkData;
+import org.roller.presentation.forms.BookmarkForm;
+
+/**
+ * Extends the BookmarkForm so that additional properties may be added.
+ * These properties are not persistent and are only needed for the UI.
+ *
+ * @struts.form name="bookmarkFormEx"
+ */
+public class BookmarkFormEx extends BookmarkForm
+{
+    private String mFolderId = null;
+
+    /**
+     *
+     */
+    public BookmarkFormEx()
+    {
+        super();
+    }
+
+    /**
+     * @param dataHolder
+     */
+    public BookmarkFormEx(BookmarkData dataHolder, java.util.Locale locale) throws RollerException
+    {
+        copyFrom(dataHolder, locale);
+    }
+
+    /**
+     * @return
+     */
+    public String getFolderId()
+    {
+        return mFolderId;
+    }
+
+    /**
+     * @param string
+     */
+    public void setFolderId(String string)
+    {
+        mFolderId = string;
+    }
+
+    /**
+     * @see org.roller.presentation.forms.BookmarkForm#setData(org.roller.pojos.BookmarkData)
+     */
+    public void copyFrom(BookmarkData dataHolder, java.util.Locale locale) throws RollerException
+    {
+        super.copyFrom(dataHolder, locale);
+        mFolderId = dataHolder.getFolder().getId();
+    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/BookmarksForm.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/BookmarksForm.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/BookmarksForm.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/BookmarksForm.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,69 @@
+/*
+ * Created on Oct 21, 2003
+ */
+package org.roller.presentation.bookmarks.formbeans;
+
+import org.apache.struts.action.ActionForm;
+
+/**
+ * @struts.form name="bookmarksForm"
+ */ 
+public class BookmarksForm extends ActionForm
+{
+    private String folderId = null; 
+    private boolean moveContents = false; 
+    private String moveToFolderId = null; 
+    private String[] selectedBookmarks = null;
+    private String[] selectedFolders = null;
+    
+    public String getFolderId()
+    {
+        return folderId;
+    }
+
+    public void setFolderId(String folderId)
+    {
+        this.folderId = folderId;
+    }
+
+    public boolean isMoveContents()
+    {
+        return moveContents;
+    }
+
+    public void setMoveContents(boolean moveContents)
+    {
+        this.moveContents = moveContents;
+    }
+
+    public String getMoveToFolderId()
+    {
+        return moveToFolderId;
+    }
+
+    public void setMoveToFolderId(String moveToFolderId)
+    {
+        this.moveToFolderId = moveToFolderId;
+    }
+
+    public String[] getSelectedBookmarks()
+    {
+        return selectedBookmarks;
+    }
+
+    public void setSelectedBookmarks(String[] selectedBookmarks)
+    {
+        this.selectedBookmarks = selectedBookmarks;
+    }
+
+    public String[] getSelectedFolders()
+    {
+        return selectedFolders;
+    }
+
+    public void setSelectedFolders(String[] selectedFolders)
+    {
+        this.selectedFolders = selectedFolders;
+    }
+
+}

Added: incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/FolderFormEx.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/FolderFormEx.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/FolderFormEx.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/FolderFormEx.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,88 @@
+
+package org.roller.presentation.bookmarks.formbeans;
+
+import org.apache.struts.upload.FormFile;
+import org.roller.RollerException;
+import org.roller.pojos.FolderData;
+import org.roller.presentation.forms.FolderForm;
+
+
+/**
+ * Extends the FolderForm so that additional properties may be added.
+ * These properties are not persistent and are only needed for the UI.
+ *  
+ * @struts.form name="folderFormEx"
+ */ 
+public class FolderFormEx extends FolderForm
+{
+	private boolean mMoveContents = false; 
+	private String mMoveToFolderId = null; 
+    private String[] mSelectedBookmarks = null;
+    private String[] mSelectedFolders = null;
+    private transient FormFile mBookmarksFile = null;
+
+	public FolderFormEx()
+	{
+		super();
+	}
+
+	public FolderFormEx(FolderData folderData, java.util.Locale locale) throws RollerException
+	{
+		super(folderData, locale);
+	}
+
+    public String getShortenedDesc() 
+    {
+        if ( getDescription().length() > 20 )
+        {
+            return getDescription().substring(0,19)+"...";
+        }
+        return getDescription();
+    }
+
+    public void setShortenedDesc( String desc )
+    {
+        // readonly
+    }
+
+    //------------------------------------------------- Property bookmarksFile 
+
+    /** Bookmark file to be imported */
+    public void setBookmarksFile(FormFile file) { mBookmarksFile = file; }
+
+    /** Bookmark file to be imported */
+    public FormFile getBookmarksFile() { return mBookmarksFile; }
+
+    //-------------------------------------------------- Property moveContents
+
+	/** If true then contents should be moved when this folder is removed */
+	public boolean getMoveContents() { return mMoveContents; }
+
+	/** If true then contents should be moved when this folder is removed */
+	public void setMoveContents( boolean flag ) { mMoveContents = flag;}
+
+    //------------------------------------------------ Property moveToFolderId
+
+	/** Folder where contents should be moved if this folder is removed */ 
+	public String getMoveToFolderId() { return mMoveToFolderId; }
+
+	/** Folder where contents should be moved if this folder is removed */ 
+	public void setMoveToFolderId( String id ) { mMoveToFolderId = id;}
+
+    //--------------------------------------------- Property selectedBookmarks 
+
+    /** Get selected bookmarks */
+    public String[] getSelectedBookmarks() { return mSelectedBookmarks; }
+
+    /** Set selected bookmarks */
+    public void setSelectedBookmarks( String[] b ) { mSelectedBookmarks = b; }
+
+    //--------------------------------------------- Property selectedBookmarks 
+
+    /** Get selected folders */
+    public String[] getSelectedFolders() { return mSelectedFolders; }
+
+    /** Set selected bookmarks */
+    public void setSelectedFolders( String[] f ) { mSelectedFolders = f; }
+}
+

Added: incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/package.html?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/package.html (added)
+++ incubator/roller/trunk/src/org/roller/presentation/bookmarks/formbeans/package.html Wed Jun  8 20:18:46 2005
@@ -0,0 +1,9 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title></title>
+</head>
+<body>
+Form beans for bookmarks forms.<br>
+</body>
+</html>

Added: incubator/roller/trunk/src/org/roller/presentation/bookmarks/tags/ViewBookmarksTag.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/bookmarks/tags/ViewBookmarksTag.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/bookmarks/tags/ViewBookmarksTag.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/bookmarks/tags/ViewBookmarksTag.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,234 @@
+package org.roller.presentation.bookmarks.tags;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.model.BookmarkManager;
+import org.roller.pojos.BookmarkComparator;
+import org.roller.pojos.BookmarkData;
+import org.roller.pojos.FolderData;
+import org.roller.pojos.UserData;
+import org.roller.presentation.RollerContext;
+import org.roller.presentation.RollerRequest;
+import org.roller.util.Utilities;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.MalformedURLException;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.jsp.tagext.Tag;
+
+
+/**
+ * @deprecated Is this class even in use anymore? -Lance
+ * 
+ * <p>Displays a folder of bookmarks or a table that shows all folders.
+ * If the folderName property is set then this tag will display the bookmarks
+ * in that folder, separated by BR tag line breaks. If the folderName
+ * property is not set, this tag will display a table of bookmarks.
+ * </p>
+ * <p>The bookmarks table display uses the Folder Column and Row values
+ * to position the Folders in a table. The bookmarks within each folder
+ * are ordered using the Bookmark Priority value. A bookmark's HREF tag
+ * is given a CSS class of rBookmark_N where N is the Bookmark's Weight value.
+ * </p>
+ * @jsp.tag name="ViewBookmarks"
+ */
+public class ViewBookmarksTag extends org.roller.presentation.tags.HybridTag
+{
+    static final long serialVersionUID = -4357415994168654686L;
+    
+    private static Log mLogger = 
+       LogFactory.getFactory().getInstance(ViewBookmarksTag.class);
+
+    /** @jsp.attribute */
+    public String getFolderName() { return mFolderName; }
+    public void setFolderName(String v) { mFolderName = v; }
+    private String mFolderName = null;
+
+    /** @jsp.attribute */
+    public String getTitle() { return mTitle; }
+    public void setTitle(String v) { mTitle = v; }
+    private String mTitle = null;
+
+    /** @jsp.attribute */
+    public boolean getShowFolderName() { return mShowFolderName; }
+    public void setShowFolderName(boolean v) { mShowFolderName = v; }
+    private boolean mShowFolderName = true;
+
+    /** @jsp.attribute */
+    public boolean getExpandingFolder() { return mExpandingFolder; }
+    public void setExpandingFolder(boolean v) { mExpandingFolder = v; }
+    private boolean mExpandingFolder = false;
+    
+    //------------------------------------------------------------------------
+
+    public String view( String folderName, String title )
+    {
+        mFolderName = folderName;
+        mTitle = title;
+        return emit();
+    }
+
+    public String view( String folderName, boolean showFolderName )
+    {
+        mFolderName = folderName;
+        mShowFolderName = showFolderName;
+        return emit();
+    }
+
+    public String view( String folderName, boolean showFolderName, boolean expandingFolder )
+    {
+        mFolderName = folderName;
+        mShowFolderName = showFolderName;
+        mExpandingFolder = expandingFolder;
+        return emit();
+    }
+    
+    //-------------------------------------------------------------
+    /**
+     * Process start tag
+     * @return EVAL_SKIP_BODY
+     */
+    public int doStartTag( PrintWriter pw ) throws JspException
+    {
+        try
+        {
+            HttpServletRequest req =
+                (HttpServletRequest)pageContext.getRequest();
+            RollerRequest rreq = RollerRequest.getRollerRequest(req);
+            BookmarkManager bookmarkMgr =
+                rreq.getRoller().getBookmarkManager();
+            UserData user = rreq.getUser();
+
+            FolderData fd = bookmarkMgr.getFolder(
+                rreq.getWebsite(), mFolderName);
+
+            if ( fd == null )
+            {
+                pw.print("<span class=\"error\">");
+                pw.print("Error fetching folder named "+mFolderName);
+                pw.print("</span>");
+                return  Tag.SKIP_BODY;
+            }
+            emitFolderHTML( pw, pageContext, fd, user );
+            return Tag.SKIP_BODY;
+        }
+        catch (Exception e)
+        {
+            mLogger.error("Exception",e);
+            throw new JspException(
+                e.getClass().toString()+": "+e.getMessage(),e);
+        }
+    }
+
+    //------------------------------------------------------------------------
+    public void emitBookmarkHTML( PrintWriter pw, PageContext ctx,
+        BookmarkData bookmark, UserData user )
+        throws IOException, MalformedURLException
+    {
+        HttpServletRequest request = (HttpServletRequest)ctx.getRequest();
+        String cpath = request.getContextPath();
+
+        String resourcePath = request.getContextPath()
+                + RollerContext.getUploadPath(pageContext.getServletContext())
+                    + "/" + user.getUserName();
+
+        if ( bookmark.getImage()!=null
+         && !bookmark.getImage().trim().equals("") )
+        {
+            pw.print("<a href=\""+bookmark.getUrl()+"\">");
+            pw.println("<img src=\""
+                + resourcePath + "/" + bookmark.getImage() + "\" "
+                + "alt=\"" + bookmark.getName() + "\" /> " );
+            pw.println("</a><br />");
+        }
+        else if ( bookmark.getFeedUrl()!=null
+              && !bookmark.getFeedUrl().trim().equals("") )
+        {
+            pw.print("<a class=\"rBookmark\" href=\""+bookmark.getUrl()+"\"");
+            if ( !bookmark.getDescription().trim().equals("") )
+            {
+                pw.print(" title=\""+bookmark.getDescription()+"\"");
+            }
+            pw.print(" >");
+            pw.println( bookmark.getName()+"</a>");
+
+            pw.println( "<a href=\""+bookmark.getFeedUrl()+"\">" );
+            pw.print  ( "<img src=\""+cpath+"/images/smrssbadge.gif\" " );
+            pw.println(     "alt=\"URL of site's RSS feed\"" );
+            pw.println(     "class=\"smrssbadge\" /></a>" );
+
+            pw.println( "<br />" );
+        }
+        else
+        {
+            pw.print( "<a href=\"" );
+            pw.print( bookmark.getUrl() );
+            pw.print( "\" " );
+            pw.print( "class=\"rBookmark" );
+            pw.print( bookmark.getWeight() );
+            pw.print( "\" " );
+            pw.print( "title=\""  );
+            pw.print( bookmark.getDescription() );
+            pw.print( "\" >" );
+            pw.print( bookmark.getName() );
+            pw.println( "</a><br />" );
+        }
+    }
+
+    //------------------------------------------------------------------------
+    public void emitFolderHTML( PrintWriter pw, PageContext ctx,
+        FolderData folder, UserData user )
+        throws IOException, MalformedURLException
+    {
+        HttpServletRequest request = (HttpServletRequest)ctx.getRequest();
+        String cpath = request.getContextPath();
+        // replace spaces with underscores
+        String divId = Utilities.stringReplace( folder.getName(), " ", "_" );
+        // remove single quotes to prevent javascript errors
+        divId = Utilities.stringReplace( divId, "'", "" );
+        
+        if ( mShowFolderName && !mExpandingFolder )
+        {
+            pw.println( "<div class=\"rFolder\">"+folder.getName()+"</div>" );
+        }
+
+        if ( mShowFolderName && mExpandingFolder )
+        {            
+            pw.print( "<div class=\"rFolder\"><a href=\"javascript:" );
+            pw.print( "toggleFolder('"+divId+"')\"><span id=\"i"+divId+"\">" );
+            pw.print( "+</span> "+folder.getName()+"</a></div>" );
+            pw.println( "<div id=\""+divId+"\" style=\"display: none\">" );       
+        }
+        
+        Collection bookmarks = folder.getBookmarks();
+        //java.util.Collections.sort( bookmarks, new BookmarkComparator() );
+        Iterator iter = bookmarks.iterator();
+        while ( iter.hasNext() )
+        {
+            BookmarkData bookmark = (BookmarkData)iter.next();
+            emitBookmarkHTML( pw, ctx, bookmark, user );
+        }
+        
+        if (mShowFolderName && mExpandingFolder)
+        {
+            pw.println( "</div>" );       
+            pw.println( "<script type=\"text/javascript\">" );
+            pw.println( "<!--" );
+            pw.println( "  folderPreference('"+divId+"');" );
+            pw.println( "// -->");
+            pw.println( "</script>" );
+        }
+    }
+}
+

Added: incubator/roller/trunk/src/org/roller/presentation/bookmarks/tags/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/bookmarks/tags/package.html?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/bookmarks/tags/package.html (added)
+++ incubator/roller/trunk/src/org/roller/presentation/bookmarks/tags/package.html Wed Jun  8 20:18:46 2005
@@ -0,0 +1,9 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title></title>
+</head>
+<body>
+JSP tags for bookmark display and editing<br>
+</body>
+</html>

Added: incubator/roller/trunk/src/org/roller/presentation/filters/BreadCrumbFilter.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/BreadCrumbFilter.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/BreadCrumbFilter.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/BreadCrumbFilter.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,127 @@
+package org.roller.presentation.filters;
+
+import org.apache.commons.collections.ArrayStack;
+import org.roller.presentation.RollerSession;
+import org.roller.util.StringUtils;
+import org.roller.util.Utilities;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+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.roller.config.RollerConfig;
+
+/**
+ * Intercepts requests and places URL
+ * into breadcrumb stack.
+ * 
+ * @web.filter name="BreadCrumbFilter"
+ * *web.filter-mapping url-pattern="/*.do"
+ * @web.filter-init-param name="maxStackSize" value="3"
+ *
+ * @author <a href="mailto:lance@brainopolis.com">Lance Lavandowska</a>
+ *
+**/
+public final class BreadCrumbFilter implements Filter
+{
+    private static Log mLogger = 
+        LogFactory.getFactory().getInstance(BreadCrumbFilter.class);
+    
+    private int mMaxStackSize = 10;
+
+    
+    public void doFilter(
+        ServletRequest req, ServletResponse resp, FilterChain chain)
+        throws IOException, ServletException
+    {
+        HttpServletRequest request = (HttpServletRequest) req;
+        HttpServletResponse response = (HttpServletResponse) resp;
+
+        HttpSession ses = request.getSession(false);
+        ArrayStack stack = null;
+        if (ses != null)
+        {
+            stack = (ArrayStack)ses.getAttribute(RollerSession.BREADCRUMB);
+        }
+        if (stack == null)
+        {
+            stack = new ArrayStack();
+        }
+
+        // This gives you a chance to look at your breadcrumb trail
+        if (request.getQueryString() != null 
+            && request.getQueryString().equals("BreadCrumb"))
+        {
+            response.setContentType("text/html; charset=UTF-8");
+            ServletOutputStream out = response.getOutputStream();
+
+            for (int i=0; i<stack.size(); i++)
+            {
+                out.println(stack.peek(i).toString() +"<br>");
+            }
+            out.flush();
+            out.close();
+        }
+        else
+        {
+            chain.doFilter(req, resp);
+        }
+
+        StringBuffer url = request.getRequestURL();
+        // now that we've successfully returned,
+        // add url to stack if it isn't a Velocity page
+        String servletPath = request.getServletPath();
+        if (servletPath.indexOf("page") == -1 &&
+            servletPath.indexOf("comments") == -1)
+        {    
+            if (request.getQueryString() != null)
+            {
+                url.append("?").append( request.getQueryString() );
+            }
+            if (stack.size() == mMaxStackSize)
+            {
+                stack.remove(mMaxStackSize-1);
+            }
+            stack.push(url.toString());
+        }
+        if (ses != null)
+        {    
+        	ses.setAttribute(RollerSession.BREADCRUMB, stack);
+        }
+    }
+
+    /**
+     * Initialize controller values of filter.
+    **/
+    public void init(FilterConfig filterConfig)
+    {
+        mLogger.debug("Initializing Breadcrumb Filter");
+
+        String stackSize = RollerConfig.getProperty("breadcrumbs.stacksize");
+        if (!StringUtils.isEmpty(stackSize))
+        {
+            int mSS = Utilities.stringToInt(stackSize);
+            if (mSS != 0)
+            {
+                mMaxStackSize = mSS;
+                mLogger.info("set breadcrumb stack size to "+mSS);
+            }
+        }
+    }
+
+    /** destroy any instance values other than filterConfig **/
+    public void destroy()
+    {
+        mMaxStackSize = 10;
+    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/filters/ByteArrayOutputStreamWrapper.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/ByteArrayOutputStreamWrapper.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/ByteArrayOutputStreamWrapper.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/ByteArrayOutputStreamWrapper.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,82 @@
+package org.roller.presentation.filters;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+import javax.servlet.ServletOutputStream;
+
+/*
+ * @author llavandowska
+ *
+ * Implementation of ServletOutputStream that allows the filter to hold the
+ * Response content for insertion into the cache.
+ */
+public class ByteArrayOutputStreamWrapper extends ServletOutputStream
+{
+    protected OutputStream intStream;
+    protected ByteArrayOutputStream baStream;
+    protected boolean finallized = false;
+    protected boolean flushOnFinalizeOnly = true;
+
+    public ByteArrayOutputStreamWrapper(OutputStream outStream)
+    {
+        intStream = outStream;
+        baStream = new ByteArrayOutputStream();
+    }
+
+    public ByteArrayOutputStreamWrapper()
+    {
+        intStream = System.out;
+        baStream = new ByteArrayOutputStream();
+    }
+
+    public ByteArrayOutputStream getByteArrayStream()
+    {
+        return baStream;
+    }
+
+    public void setFinallized()
+    {
+        finallized = true;
+    }
+
+    public boolean isFinallized()
+    {
+        return finallized;
+    }
+
+
+    public void write(int i) throws java.io.IOException
+    {
+        baStream.write(i);
+    }
+
+    public void close() throws java.io.IOException
+    {
+        if (finallized) {
+            processStream();
+            intStream.close();
+        }
+    }
+
+    public void flush() throws java.io.IOException
+    {
+        if (baStream.size() != 0) {
+            if (!flushOnFinalizeOnly || finallized) {
+                processStream();
+                baStream = new ByteArrayOutputStream();
+            }
+        }
+    }
+
+    protected void processStream() throws java.io.IOException
+    {
+        intStream.write(baStream.toByteArray());
+        intStream.flush();
+    }
+    
+    public void clear()
+    {
+        baStream = new ByteArrayOutputStream();
+    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/filters/ByteArrayResponseWrapper.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/ByteArrayResponseWrapper.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/ByteArrayResponseWrapper.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/ByteArrayResponseWrapper.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,53 @@
+package org.roller.presentation.filters;
+
+import java.io.PrintWriter;
+import java.io.OutputStreamWriter;
+import java.io.ByteArrayOutputStream;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+/*
+ * @author llavandowska
+ *
+ * Implementation of HttpServletResponseWrapper.
+ */
+public class ByteArrayResponseWrapper extends HttpServletResponseWrapper
+{
+    private PrintWriter tpWriter;
+    private ByteArrayOutputStreamWrapper tpStream;
+
+    public ByteArrayResponseWrapper(ServletResponse inResp)
+    throws java.io.IOException
+    {
+        super((HttpServletResponse) inResp);
+        tpStream = new ByteArrayOutputStreamWrapper(inResp.getOutputStream());
+        tpWriter = new PrintWriter(new OutputStreamWriter(tpStream,"UTF-8"));
+    }
+
+    public ServletOutputStream getOutputStream()
+    throws java.io.IOException
+    {
+        return tpStream;
+    }
+
+    public PrintWriter getWriter() throws java.io.IOException
+    {
+        return tpWriter;
+    }
+     
+    /** Get a String representation of the entire buffer.
+     */    
+    public String toString()
+    {
+        return tpStream.getByteArrayStream().toString();
+    }
+    
+    public ByteArrayOutputStream getByteArrayOutputStream()
+    throws java.io.IOException
+    {
+        return tpStream.getByteArrayStream();
+    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/filters/CompressionFilter.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/CompressionFilter.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/CompressionFilter.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/CompressionFilter.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,125 @@
+package org.roller.presentation.filters;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.GZIPOutputStream;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/** Filter that compresses output with gzip
+ *  (assuming that browser supports gzip).
+ *  <P>
+ *  Taken from More Servlets and JavaServer Pages
+ *  from Prentice Hall and Sun Microsystems Press,
+ *  http://www.moreservlets.com/.
+ *  &copy; 2002 Marty Hall; may be freely used or adapted.
+ * 
+ * @web.filter name="PageGzipFilter"
+ * *web.filter-mapping url-pattern="/page/*"
+ */
+
+public class CompressionFilter implements Filter
+{
+    private static Log mLogger =
+        LogFactory.getFactory().getInstance(CompressionFilter.class);
+        
+	/** If browser does not support gzip, invoke resource
+	 *  normally. If browser <I>does</I> support gzip,
+	 *  set the Content-Encoding response header and
+	 *  invoke resource with a wrapped response that
+	 *  collects all the output. Extract the output
+	 *  and write it into a gzipped byte array. Finally,
+	 *  write that array to the client's output stream.
+	 */
+	public void doFilter(
+		ServletRequest request,
+		ServletResponse response,
+		FilterChain chain)
+		throws ServletException, IOException
+	{
+		HttpServletRequest req = (HttpServletRequest) request;
+		HttpServletResponse res = (HttpServletResponse) response;
+		if (!isGzipSupported(req))
+		{
+			// Invoke resource normally.
+			chain.doFilter(req, res);
+		}
+		else
+		{
+			// Tell browser we are sending it gzipped data.
+			res.setHeader("Content-Encoding", "gzip");
+
+			// Invoke resource, accumulating output in the wrapper.
+            ByteArrayResponseWrapper responseWrapper =
+                new ByteArrayResponseWrapper(response);
+            
+			chain.doFilter(req, responseWrapper);
+
+            ByteArrayOutputStream outputStream = responseWrapper.getByteArrayOutputStream();
+
+			// Get character array representing output.
+            if (mLogger.isDebugEnabled())
+            {
+                mLogger.debug("Pre-zip size:" + outputStream.size());
+            }
+            
+			// Make a writer that compresses data and puts
+			// it into a byte array.
+			ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+			GZIPOutputStream zipOut = new GZIPOutputStream(byteStream);
+
+			// Compress original output and put it into byte array.
+            zipOut.write(responseWrapper.getByteArrayOutputStream().toByteArray());
+
+			// Gzip streams must be explicitly closed.
+            zipOut.close();
+
+            if (mLogger.isDebugEnabled())
+            {
+                mLogger.debug("Gzip size:" + byteStream.size());
+            }
+            
+            // Update the Content-Length header.
+			res.setContentLength(byteStream.size());
+
+            ByteArrayOutputStreamWrapper newOut =
+                (ByteArrayOutputStreamWrapper) responseWrapper.getOutputStream();
+            newOut.clear();
+            newOut.setFinallized();
+        
+            /* now force close of OutputStream */
+            newOut.write(byteStream.toByteArray());
+            newOut.close();            
+		}
+	}
+
+	/** Store the FilterConfig object in case subclasses
+	 *  want it.
+	 */
+	public void init(FilterConfig config) throws ServletException
+	{
+	}
+
+	public void destroy()
+	{
+	}
+
+	private boolean isGzipSupported(HttpServletRequest req)
+	{
+		String browserEncodings = req.getHeader("Accept-Encoding");
+		return (
+			(browserEncodings != null)
+				&& (browserEncodings.indexOf("gzip") != -1));
+	}
+ 
+}

Added: incubator/roller/trunk/src/org/roller/presentation/filters/IPBanFilter.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/IPBanFilter.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/IPBanFilter.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/IPBanFilter.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,75 @@
+
+package org.roller.presentation.filters;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.util.StringUtils;
+
+/**
+ * Braindead simple IPBanFilter. XDoclet tags disabled because I don't want this
+ * to be on by default. Users who want it can configure it themselves in web.xml.
+ * web.filter name="IPBanFilter"
+ * web.filter-init-param name="denyFrom" value="" description="Comma-separated list of banned IPs"
+ * @author David M Johnson
+ */
+public class IPBanFilter implements Filter
+{
+    private List denyFrom = null;
+    private static Log mLogger =
+        LogFactory.getFactory().getInstance(IPBanFilter.class);
+    
+    public IPBanFilter()
+    {
+        super();
+    }
+
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+        /*
+         * This should be updated to the new config, however I don't want
+         * to do it myself since I'm not sure if/how it is being used.
+         * 
+         * This looks like something that could be a long list, so maybe
+         * it should be in the DB or possibly its own file?
+         * -- Allen G
+         */
+        String denyFromParam = filterConfig.getInitParameter("denyFrom");
+        denyFrom = Arrays.asList(StringUtils.split(denyFromParam,","));
+    }
+
+    public void doFilter(
+        ServletRequest req,
+        ServletResponse res,
+        FilterChain chain)
+        throws IOException, ServletException
+    {
+        HttpServletRequest request = (HttpServletRequest) req;
+        HttpServletResponse response = (HttpServletResponse) res;
+        if (denyFrom.contains(request.getRemoteAddr()))
+        {
+            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+            return;
+        }
+        else 
+        {            
+            chain.doFilter(request, response);
+        }
+    }
+
+    public void destroy() 
+    {
+    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/filters/IfModifiedFilter.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/IfModifiedFilter.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/IfModifiedFilter.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/IfModifiedFilter.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,230 @@
+/*
+ * Created on Apr 19, 2003
+ */
+package org.roller.presentation.filters;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.RollerException;
+import org.roller.model.Roller;
+import org.roller.model.WeblogManager;
+import org.roller.pojos.UserData;
+import org.roller.presentation.RollerContext;
+import org.roller.presentation.RollerRequest;
+import org.roller.util.LRUCache2;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.roller.config.RollerConfig;
+
+/**
+ * Entry point filter for Newsfeed Servlets, this filter 
+ * Handles If-Modified-Since header using per-user and per-category
+ * last weblog pub time. Returns 304 if requested weblog has not been
+ * modified since. Also, sets Last-Modified on outgoing response.
+ *
+ * @web.filter name="IfModifiedFilter"
+ * 
+ * @web.filter-init-param name="cacheSize" value="300"
+ *     description="Number of entries in the last modified date cache"
+ * 
+ * @web.filter-init-param name="cacheTimeout" value="1800"
+ *     description="Timeout (in seconds) of last modified date cache"
+ *
+ * @author David M Johnson
+ */
+public class IfModifiedFilter implements Filter
+{
+    private static Log mLogger =
+        LogFactory.getFactory().getInstance(IfModifiedFilter.class);
+
+    // TODO: make cache configurable
+    private static int mCacheSize = 300;
+    private static int mCacheTime = 1800;
+    private static LRUCache2 mDateCache = null;
+    SimpleDateFormat dateFormatter = 
+        new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy");
+
+    public IfModifiedFilter()
+    {
+        super();
+    }
+
+    /**
+     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+     */
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+        mLogger.debug("Initializing IfModified Filter");
+        
+        String cacheSizeString = RollerConfig.getProperty("cache.filter.ifmodified.size");
+        String cacheTimeString = RollerConfig.getProperty("cache.filter.ifmodified.timeout");
+        
+        try 
+        {
+            if (cacheSizeString != null) mCacheSize = Integer.parseInt(cacheSizeString);
+        }
+        catch (Throwable e) 
+        {
+            mLogger.warn("ERROR parsing cache size");
+        }
+        try 
+        {
+            if (cacheTimeString != null) mCacheTime = Integer.parseInt(cacheTimeString);
+        }
+        catch (Throwable e) 
+        {
+            mLogger.warn("ERROR parsing cache time");
+        }
+        
+        mLogger.info("cache size is: "+mCacheSize);
+        mLogger.info("cache timeout is: "+mCacheTime);
+        
+        mDateCache = new LRUCache2(mCacheSize, mCacheTime*60*1000);
+    }
+    
+    /**
+     * Some containers don't call init() until doFilter() is used,
+     * so always check to see if mDateCache is instantiated yet.
+     */
+    private static LRUCache2 getCache()
+    {
+        if (mDateCache == null)
+        {
+            mDateCache = new LRUCache2(mCacheSize, mCacheTime*60*1000);
+        }
+        return mDateCache;
+    }
+
+    /**
+     * @see javax.servlet.Filter#doFilter(
+     * javax.servlet.ServletRequest,
+     * javax.servlet.ServletResponse,
+     * javax.servlet.FilterChain)
+     */
+    public void doFilter(
+        ServletRequest req,
+        ServletResponse res,
+        FilterChain chain)
+        throws IOException, ServletException
+    {
+        HttpServletRequest request = (HttpServletRequest) req;
+        HttpServletResponse response = (HttpServletResponse) res;
+
+        Date updateTime = null;
+        try
+        {
+            updateTime = getLastPublishedDate(request);
+
+            // RSS context loader needs updateTime, so stash it
+            request.setAttribute("updateTime", updateTime);
+
+            // Check the incoming if-modified-since header
+            Date sinceDate =
+                new Date(request.getDateHeader("If-Modified-Since"));
+
+            if (updateTime != null)
+            {
+                 // convert date (JDK 1.5 workaround)
+                 String date = dateFormatter.format(updateTime);
+                 updateTime = new Date(date);
+                 if (updateTime.compareTo(sinceDate) <= 0)
+                 {
+                     response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+                     return;
+                 }
+            }
+            mLogger.debug("Not returning 304 for: "+request.getRequestURI());
+        }
+        catch (RollerException e)
+        {
+            // Thrown by getLastPublishedDate if there is a db-type error
+            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+            return;
+        }
+        catch (IllegalArgumentException e)
+        {
+            // Thrown by getDateHeader if not in valid format. This can be
+            // safely ignored, the only consequence is that the NOT MODIFIED
+            // response is not set.
+        }
+
+        // Set outgoing last modified header
+        if (updateTime != null)
+        {
+            response.setDateHeader("Last-Modified", updateTime.getTime());
+        }
+
+        chain.doFilter(request, response);
+    }
+
+    public static Date getLastPublishedDate(HttpServletRequest request)
+        throws RollerException
+    {
+        // Get user name without using heavy RollerRequest URL parser
+        String userName = null;
+        String pathInfo = request.getPathInfo();
+        pathInfo = pathInfo != null ? pathInfo : "";
+        String[] pathInfoArray = StringUtils.split(pathInfo, "/");
+        if (pathInfoArray.length == 1)
+        {
+            userName = pathInfoArray[0];
+        }
+        else if (pathInfoArray.length > 1) 
+        {
+            // request is for a specific date or anchor, can't return 304
+            return null;
+        }
+    
+        // Get last pub time for specific weblog category requested
+        String catname =
+            request.getParameter(RollerRequest.WEBLOGCATEGORYNAME_KEY);
+    
+        // update times are cached to reduce database queries per request
+        StringBuffer sb = new StringBuffer();
+            sb.append("zzz_");
+        sb.append(userName);
+            sb.append("_zzz_");
+        sb.append(catname);
+        String key = sb.toString();
+    
+        Date updateTime = (Date)getCache().get(key);
+        if (updateTime == null)
+        {
+            mLogger.debug("Hitting database for update time: "+key);
+            Roller roller = RollerContext.getRoller(request);
+            WeblogManager wmgr = roller.getWeblogManager();
+            updateTime = wmgr.getWeblogLastPublishTime(userName, catname);  
+            getCache().put(key, updateTime);
+        }
+        return updateTime;
+    }
+    
+    public static void purgeDateCache(UserData user) 
+    {
+        String userName = (user != null) ? user.getUserName() : null;
+        StringBuffer sb = new StringBuffer();
+        sb.append("zzz_");
+        sb.append(userName);
+        sb.append("_zzz_");
+        getCache().purge(new String[] {sb.toString()});
+    }
+
+    /**
+     * @see javax.servlet.Filter#destroy()
+     */
+    public void destroy()
+    {
+    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/filters/IfPlanetModifiedFilter.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/IfPlanetModifiedFilter.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/IfPlanetModifiedFilter.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/IfPlanetModifiedFilter.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,137 @@
+package org.roller.presentation.filters;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.RollerException;
+import org.roller.model.Roller;
+import org.roller.presentation.RollerRequest;
+
+/**
+ * Entry point filter for Newsfeed Servlets, this filter 
+ * Handles If-Modified-Since header using per-user and per-category
+ * last weblog pub time. Returns 304 if requested weblog has not been
+ * modified since. Also, sets Last-Modified on outgoing response.
+ *
+ * @web.filter name="IfPlanetModifiedFilter"
+ * @web.filter-mapping url-pattern="/planetrss/*"
+ * 
+ * @author David M Johnson
+ */
+public class IfPlanetModifiedFilter implements Filter
+{
+    private static Log mLogger =
+        LogFactory.getFactory().getInstance(IfPlanetModifiedFilter.class);
+
+    SimpleDateFormat dateFormatter = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy");
+
+    public IfPlanetModifiedFilter()
+    {
+        super();
+    }
+
+    /**
+     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
+     */
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+    }
+
+    /**
+     * @see javax.servlet.Filter#doFilter(
+     * javax.servlet.ServletRequest,
+     * javax.servlet.ServletResponse,
+     * javax.servlet.FilterChain)
+     */
+    public void doFilter(
+        ServletRequest req,
+        ServletResponse res,
+        FilterChain chain)
+        throws IOException, ServletException
+    {
+        HttpServletRequest request = (HttpServletRequest) req;
+        HttpServletResponse response = (HttpServletResponse) res;
+
+        Date updateTime = null;
+        try
+        {
+            updateTime = getLastPublishedDate(request);
+
+            // RSS context loader needs updateTime, so stash it
+            request.setAttribute("updateTime", updateTime);
+
+            // Check the incoming if-modified-since header
+            Date sinceDate =
+                new Date(request.getDateHeader("If-Modified-Since"));
+
+            if (updateTime != null)
+            {
+                 // convert date (JDK 1.5 workaround)
+                 synchronized (dateFormatter)
+                 {
+                     String date = dateFormatter.format(updateTime);
+                     updateTime = new Date(date);
+                 }
+                 if (updateTime.compareTo(sinceDate) <= 0)
+                 {
+                     response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+                     return;
+                 }
+            }
+            mLogger.debug("Not returning 304 for: "+request.getRequestURI());
+        }
+        catch (RollerException e)
+        {
+            // Thrown by getLastPublishedDate if there is a db-type error
+            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+            return;
+        }
+        catch (IllegalArgumentException e)
+        {
+            // Thrown by getDateHeader if not in valid format. This can be
+            // safely ignored, the only consequence is that the NOT MODIFIED
+            // response is not set.
+        }
+
+        // Set outgoing last modified header
+        if (updateTime != null)
+        {
+            response.setDateHeader("Last-Modified", updateTime.getTime());
+        }
+
+        chain.doFilter(request, response);
+    }
+
+    public static Date getLastPublishedDate(HttpServletRequest request)
+	    throws RollerException
+	{
+        RollerRequest rreq = RollerRequest.getRollerRequest(request);
+        Roller roller = rreq.getRoller();
+        Date lastUpdated = roller.getPlanetManager().getLastUpdated();
+        if (lastUpdated == null)
+        {
+            lastUpdated = new Date();
+            mLogger.warn("Can't get lastUpdate time, using current time instead");
+        }
+        return lastUpdated;
+	}
+
+    /**
+     * @see javax.servlet.Filter#destroy()
+     */
+    public void destroy()
+    {
+    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/filters/LoginFilter.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/LoginFilter.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/LoginFilter.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/LoginFilter.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,141 @@
+package org.roller.presentation.filters;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.config.RollerConfig;
+import org.roller.model.UserManager;
+import org.roller.pojos.UserData;
+import org.roller.presentation.util.RequestUtil;
+import org.roller.presentation.RollerRequest;
+import org.roller.util.Utilities;
+
+
+/**
+ * <p>Intercepts Login requests for "Remember Me" functionality.</p>
+ *
+ * @author Matt Raible
+ * @version $Revision: 1.4 $ $Date: 2005/05/17 20:30:16 $
+ *
+ * @web.filter display-name="Login Filter" name="loginFilter"
+ * @web.filter-init-param name="enabled" value="true"
+ */
+public final class LoginFilter implements Filter 
+{
+    //~ Instance fields ========================================================
+
+    private Log mLogger = LogFactory.getLog(LoginFilter.class);
+    private boolean enabled = true;
+
+    //~ Methods ================================================================
+
+    public void doFilter(ServletRequest req, ServletResponse resp,
+                         FilterChain chain)
+                  throws IOException, ServletException 
+    {
+
+        HttpServletRequest request = (HttpServletRequest) req;
+        HttpServletResponse response = (HttpServletResponse) resp;
+
+        // See if the user has a remember me cookie
+        Cookie c = RequestUtil.getCookie(request, RollerRequest.LOGIN_COOKIE);
+
+        try 
+        {
+            RollerRequest rreq = RollerRequest.getRollerRequest(request);
+            UserManager mgr = rreq.getRoller().getUserManager();
+                
+            // Check to see if the user is logging out, if so, remove all
+            // login cookies
+            if (request.getRequestURL().indexOf("logout") != -1) 
+            {
+                if (mLogger.isDebugEnabled()) 
+                {
+                    mLogger.debug("logging out '" + request.getRemoteUser() + "'");
+                }
+    
+                mgr.removeLoginCookies(request.getRemoteUser());
+                rreq.getRoller().commit();
+                RequestUtil.deleteCookie(response, c, request.getContextPath());
+            } 
+            else if (c != null && enabled) 
+            {
+                String loginCookie = mgr.checkLoginCookie(c.getValue());
+                rreq.getRoller().commit();
+
+                if (loginCookie != null) 
+                {
+                    RequestUtil.setCookie(response, RollerRequest.LOGIN_COOKIE,
+                                          loginCookie,
+                                          request.getContextPath());
+                    loginCookie = Utilities.decodeString(loginCookie);
+
+                    String[] value = StringUtils.split(loginCookie, '|');
+
+                    UserData user = mgr.getUser( value[0] );
+
+                    // authenticate user without displaying login page
+                    String route = "/auth?j_username=" +
+                                   user.getUserName() + "&j_password=" +
+                                   user.getPassword();
+
+                    request.setAttribute("encrypt", "false");
+                    request.getSession().setAttribute("cookieLogin", "true");
+
+                    if (mLogger.isDebugEnabled()) 
+                    {
+                        mLogger.debug("I remember you '" + user.getUserName() +
+                                  "', attempting to authenticate...");
+                    }
+
+                    RequestDispatcher dispatcher =
+                        request.getRequestDispatcher(route);
+                    dispatcher.forward(request, response);
+
+                    return;
+                }
+            }
+                
+        } catch (Exception e) 
+        {
+            // no big deal if cookie-based authentication fails
+            mLogger.warn(e.getMessage());
+        }
+
+        chain.doFilter(req, resp);
+    }
+
+    /**
+     * Initialize controller values of filter.
+     */
+    public void init(FilterConfig config) 
+    {
+        mLogger.debug("Initializing Login Filter");
+        
+        String param = RollerConfig.getProperty("loginfilter.rememberme.enabled");
+        enabled = Boolean.valueOf(param).booleanValue();
+
+        mLogger.info("Remember Me enabled: " + enabled);
+
+        config.getServletContext().setAttribute("rememberMeEnabled", param);
+    }
+
+    /**
+     * destroy any instance values other than config *
+     */
+    public void destroy() {
+    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/filters/PersistenceSessionFilter.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/PersistenceSessionFilter.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/PersistenceSessionFilter.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/PersistenceSessionFilter.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,73 @@
+package org.roller.presentation.filters;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.RollerException;
+import org.roller.model.Roller;
+import org.roller.presentation.RollerContext;
+
+/**
+ * Sole responsibility is to ensure that each request's Roller 
+ * persistence session is released at end of the request.
+ * @web.filter name="PersistenceSessionFilter"
+ * @author David M. Johnson
+ */
+public class PersistenceSessionFilter implements Filter
+{
+    private static Log mLogger =
+        LogFactory.getFactory().getInstance(RequestFilter.class);
+
+    /**
+     * destroy
+     */
+    public void destroy()
+    {
+    }
+
+    /**
+     * Release Roller persistence session at end of request processing.
+     */
+    public void doFilter(
+        ServletRequest req, ServletResponse res, FilterChain chain)
+        throws IOException, ServletException
+    {
+        HttpServletRequest request = (HttpServletRequest)req;
+        HttpServletResponse response = (HttpServletResponse)res;
+        if (mLogger.isDebugEnabled())
+        {
+            mLogger.debug("Entered PersistenceSessionFilter");
+        }
+        Roller roller = RollerContext.getRoller((HttpServletRequest)request);
+        try 
+        {
+            chain.doFilter(request, response);
+        }
+        finally 
+        {
+            roller.release();
+        }
+        if (mLogger.isDebugEnabled())
+        {
+            mLogger.debug("Exiting PersistenceSessionFilter");
+        }
+    }
+
+    /**
+     * init
+     */
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+    }
+}
+

Added: incubator/roller/trunk/src/org/roller/presentation/filters/RefererFilter.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/filters/RefererFilter.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/filters/RefererFilter.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/filters/RefererFilter.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,130 @@
+package org.roller.presentation.filters;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.model.RefererManager;
+import org.roller.presentation.RollerContext;
+import org.roller.presentation.RollerRequest;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+
+/**
+ * Keep track of referers.
+ * 
+ * @web.filter name="RefererFilter"
+ * *web.filter-mapping url-pattern="/page/*"
+ * 
+ * @author David M. Johnson
+ */
+public class RefererFilter implements Filter
+{
+    private FilterConfig   mFilterConfig = null;
+    private static Log mLogger = 
+        LogFactory.getFactory().getInstance(RefererFilter.class);
+   
+    /**
+     * destroy
+     */
+    public void destroy()
+    {
+    }
+
+    /**
+     * doFilter
+     */
+    public void doFilter(
+        ServletRequest req, ServletResponse res, FilterChain chain)
+        throws IOException, ServletException
+    {
+        HttpServletRequest request = (HttpServletRequest)req;
+        boolean isRefSpammer = false;       
+        try
+        {
+            RollerRequest rreq = RollerRequest.getRollerRequest(request);
+            RollerContext rctx = RollerContext.getRollerContext(
+                mFilterConfig.getServletContext());
+            
+            if ( rreq.getUser() != null )
+            {
+                String userName = rreq.getUser().getUserName();                
+                
+                // Base page URLs, with and without www.
+                String basePageUrlWWW = 
+                    rctx.getAbsoluteContextUrl(request)+"/page/"+userName;                        
+                String basePageUrl = basePageUrlWWW;          
+                if ( basePageUrlWWW.startsWith("http://www.") )
+                {
+                    // chop off the http://www.
+                    basePageUrl = "http://"+basePageUrlWWW.substring(11);
+                }
+                                 
+                // Base comment URLs, with and without www.  
+                String baseCommentsUrlWWW = 
+                    rctx.getAbsoluteContextUrl(request)+"/comments/"+userName;   
+                String baseCommentsUrl = baseCommentsUrlWWW;          
+                if ( baseCommentsUrlWWW.startsWith("http://www.") )
+                {
+                    // chop off the http://www.
+                    baseCommentsUrl= "http://"+baseCommentsUrlWWW.substring(11);
+                }
+                
+                // Don't process hits from same user's blogs as referers by
+                // ignoring Don't process referer from pages that start with base URLs. 
+                String referer = request.getHeader("Referer");               
+                if (  referer==null ||
+                      ( 
+                         !referer.startsWith( basePageUrl ) 
+                      && !referer.startsWith( basePageUrlWWW )
+                      && !referer.startsWith( baseCommentsUrl )
+                      && !referer.startsWith( baseCommentsUrlWWW )
+                      )
+                   )
+                {
+                    RefererManager refMgr = 
+                        rreq.getRoller().getRefererManager();
+                    isRefSpammer = refMgr.processRequest(rreq);
+                }
+                else
+                {
+                    if (mLogger.isDebugEnabled())
+                    {
+                        mLogger.debug("Ignoring referer="+referer);
+                    }
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            mLogger.error("Processing referer",e);
+        }
+        
+        if (isRefSpammer)
+        {
+            HttpServletResponse response = (HttpServletResponse)res;
+            response.sendError(HttpServletResponse.SC_FORBIDDEN);            
+        }
+        else
+        {
+            chain.doFilter(req, res);
+        }
+    }
+
+    /**
+     * init
+     */
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+        mFilterConfig = filterConfig;
+    }
+}



Mime
View raw message