You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by ag...@apache.org on 2005/07/06 02:00:37 UTC

svn commit: r209360 - in /incubator/roller/trunk: src/org/roller/presentation/velocity/PreviewServlet.java src/org/roller/presentation/website/actions/ThemeEditorAction.java web/website/theme-editor.jsp

Author: agilliland
Date: Tue Jul  5 17:00:35 2005
New Revision: 209360

URL: http://svn.apache.org/viewcvs?rev=209360&view=rev
Log:
Rewrote ThemeEditorAction and PreviewServlet for new theme management stuff.

PreviewServlet now works completely independently and can provide full page previews of any theme at any time simply by setting ?theme=<theme> on the url

Modified:
    incubator/roller/trunk/src/org/roller/presentation/velocity/PreviewServlet.java
    incubator/roller/trunk/src/org/roller/presentation/website/actions/ThemeEditorAction.java
    incubator/roller/trunk/web/website/theme-editor.jsp

Modified: incubator/roller/trunk/src/org/roller/presentation/velocity/PreviewServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/velocity/PreviewServlet.java?rev=209360&r1=209359&r2=209360&view=diff
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/velocity/PreviewServlet.java (original)
+++ incubator/roller/trunk/src/org/roller/presentation/velocity/PreviewServlet.java Tue Jul  5 17:00:35 2005
@@ -1,26 +1,139 @@
 
 package org.roller.presentation.velocity;
 
+import java.io.StringWriter;
 import org.apache.velocity.Template;
 import org.apache.velocity.context.Context;
-
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.JspFactory;
+import javax.servlet.jsp.PageContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.roller.ThemeNotFoundException;
+import org.roller.model.Roller;
+import org.roller.model.RollerFactory;
+import org.roller.model.ThemeManager;
+import org.roller.model.UserManager;
+import org.roller.pojos.Theme;
+import org.roller.pojos.UserData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.RollerRequest;
+
 
 /**
- * Extend RollerServlet to load proper resource loader for page execution.
- * 
+ * Allow users to preview what their blog would look like in a given theme.
+ *
  * @web.servlet name="PreviewServlet" load-on-startup="1"
- * @web.servlet-init-param name="properties" value="/WEB-INF/velocity.properties" 
+ * @web.servlet-init-param name="properties" value="/WEB-INF/velocity.properties"
  * @web.servlet-mapping url-pattern="/preview/*"
- */ 
-public class PreviewServlet extends BasePageServlet
-{
+ */
+public class PreviewServlet extends BasePageServlet {
+    
+    private static Log mLogger =
+            LogFactory.getFactory().getInstance(PreviewServlet.class);
+    
+    
+    /**
+     * We function exactly like the PageServlet except that we temporarily
+     * modify the users theme for this request.
+     */
     public Template handleRequest( HttpServletRequest request,
-                                    HttpServletResponse response, 
-                                    Context ctx ) throws Exception
-    {
-        return super.handleRequest(request, response, ctx);
+            HttpServletResponse response,
+            Context ctx ) throws Exception {
+        
+        Theme previewTheme = null;
+        
+        // try getting the preview theme
+        String themeName = request.getParameter("theme");
+        if(themeName != null) {
+            try {
+                Roller roller = RollerFactory.getRoller();
+                ThemeManager themeMgr = roller.getThemeManager();
+                previewTheme = themeMgr.getTheme(themeName);
+                
+            } catch(ThemeNotFoundException tnfe) {
+                // bogus theme specified ... don't worry about it
+                // possibly "custom", but we'll handle that below
+            }
+        }
+        
+        if((previewTheme == null || !previewTheme.isEnabled()) &&
+                !themeName.equals(Theme.CUSTOM)) {
+            
+            // if we don't have a valid preview theme then
+            // leave it up to our parent
+            return super.handleRequest(request, response, ctx);
+        }
+        
+        
+        Template outty = null;
+        Exception pageException = null;
+        
+        try {
+            PageContext pageContext =
+                    JspFactory.getDefaultFactory().getPageContext(
+                    this, request, response,"", true, 8192, true);
+            // Needed to init request attributes, etc.
+            RollerRequest rreq = RollerRequest.getRollerRequest(pageContext);
+            UserManager userMgr = RollerFactory.getRoller().getUserManager();
+            
+            WebsiteData website = null;
+            if (request.getAttribute(RollerRequest.OWNING_USER) != null) {
+                UserData user = (UserData)
+                    request.getAttribute(RollerRequest.OWNING_USER);
+                website = userMgr.getWebsite(user.getUserName());
+            } else {
+                website = rreq.getWebsite();
+            }
+            
+            // construct a temporary Website object for this request
+            // and set the EditorTheme to our previewTheme
+            WebsiteData tmpWebsite = new WebsiteData();
+            tmpWebsite.setData(website);
+            if(previewTheme != null)
+                tmpWebsite.setEditorTheme(previewTheme.getName());
+            else
+                tmpWebsite.setEditorTheme(Theme.CUSTOM);
+            
+            org.roller.model.Template page = null;
+            
+            // If request specified the page, then go with that
+            page = tmpWebsite.getDefaultPage();
+            rreq.setPage(page);
+            rreq.setWebsite(tmpWebsite);
+            
+            // Still no page ID, then we have a problem
+            if ( page == null ) {
+                throw new ResourceNotFoundException("Page not found");
+            }
+
+            // this sets up the page we want to render
+            outty = prepareForPageExecution(ctx, rreq, response, page);
+            
+            // if there is a decorator template then apply it
+            if (website != null) {
+                // parse/merge Page template
+                StringWriter sw = new StringWriter();
+                outty.merge(ctx, sw);
+                ctx.put("decorator_body", sw.toString());
+                
+                // replace outty with decorator Template
+                outty = findDecorator(tmpWebsite, (String) ctx.get("decorator"));
+            }
+            
+        } catch( Exception e ) {
+            pageException = e;
+            response.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+        }
+        
+        if (pageException != null) {
+            mLogger.error("EXCEPTION: in RollerServlet", pageException);
+            request.setAttribute("DisplayException", pageException);
+        }
+        
+        return outty;
     }
 }
 

Modified: incubator/roller/trunk/src/org/roller/presentation/website/actions/ThemeEditorAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/website/actions/ThemeEditorAction.java?rev=209360&r1=209359&r2=209360&view=diff
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/website/actions/ThemeEditorAction.java (original)
+++ incubator/roller/trunk/src/org/roller/presentation/website/actions/ThemeEditorAction.java Tue Jul  5 17:00:35 2005
@@ -1,651 +1,412 @@
 package org.roller.presentation.website.actions;
 
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import javax.servlet.ServletException;
+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.actions.DispatchAction;
 import org.roller.RollerException;
-import org.roller.model.UserManager;
 import org.roller.pojos.WeblogTemplate;
-import org.roller.pojos.UserData;
 import org.roller.pojos.WebsiteData;
-import org.roller.presentation.RollerContext;
 import org.roller.presentation.RollerRequest;
-import org.roller.presentation.pagecache.PageCacheFilter;
-import org.roller.presentation.velocity.PreviewResourceLoader;
-import org.roller.presentation.website.ThemeCache;
-import org.roller.presentation.website.formbeans.ThemeEditorForm;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
+import org.roller.ThemeNotFoundException;
 import org.roller.config.RollerRuntimeConfig;
+import org.roller.model.Roller;
+import org.roller.model.RollerFactory;
+import org.roller.model.ThemeManager;
+import org.roller.model.UserManager;
+import org.roller.pojos.Theme;
+import org.roller.pojos.ThemeTemplate;
+import org.roller.presentation.pagecache.PageCacheFilter;
 
 
-/////////////////////////////////////////////////////////////////////////////
-
 /**
- * Actions for theme chooser page.
- * 
- * @author llavandowska
- * 
+ * Struts Action class that handles the website theme chooser page.
+ *
+ * @author Allen Gilliland
+ *
  * @struts.action name="themeEditorForm" path="/editor/themeEditor"
  *    scope="session" parameter="method"
- * 
+ *
  * @struts.action-forward name="editTheme.page" path="/website/theme-editor.jsp"
  */
-public class ThemeEditorAction extends DispatchAction
-{
-	private static final String SESSION_TEMPLATE = "weblog.template";
-    private static final String LAST_THEME = "weblog.prev.theme";
-    private static Log mLogger = 
-        LogFactory.getFactory().getInstance(ThemeEditorAction.class);
-    private ThemeCache themeCache = ThemeCache.getInstance();
-	
-	/**
-     * Take user to edit theme page.
-     * 
-     * @param mapping Struts action mapping.
-     * @param form Theme editor form bean.
-     * @param request Servlet request.
-     * @param response Servlet response.
-     * @return Forward to edit-website page.
-     * @throws IOException
-     * @throws ServletException
-	 */
-	//-----------------------------------------------------------------------
-	public ActionForward edit(
-		ActionMapping       mapping,
-		ActionForm          form,
-		HttpServletRequest  request,
-		HttpServletResponse response)
-		throws IOException, ServletException
-	{
-		ActionErrors errors = new ActionErrors();
-		ActionForward forward = mapping.findForward("editTheme.page");
-		try
-		{
-			RollerRequest rreq = RollerRequest.getRollerRequest(request);
-			if ( rreq.isUserAuthorizedToEdit() )
-			{
-				loadThemes( rreq, errors, true);
-				ThemeEditorForm teForm = (ThemeEditorForm)form;
-				
-				teForm.setThemeName(null); // start fresh
-                
-                if (mLogger.isDebugEnabled())
-                {
-                    mLogger.debug("loaded themes, form="+teForm);
-                }  
-                
-//				// if a custom template has been previewed already,
-//				// it'll be in memory.
-//				String template = 
-//                   (String)request.getSession().getAttribute(SESSION_TEMPLATE);
-//                
-//                if (mLogger.isDebugEnabled())
-//                {
-//                    mLogger.debug("got template="+template);
-//                }
-//                
-//				if (StringUtils.isNotEmpty(template))
-//				{
-//					// load the template in memory
-//					teForm.setThemeTemplate( template );
-//                    
-//                    if (mLogger.isDebugEnabled())
-//                    {
-//                        mLogger.debug("set template");
-//                    }
-//				}
-//				// otherwise the "custom" template will need be loaded
-//				// from the current page.
-//				else
-//				{
-                
-				// clear any previously set themes
-                clearThemePages(rreq, 
-					(String)request.getSession(true).getAttribute(LAST_THEME)); 
-                                
-			     // load the current default page
-                WeblogTemplate page = getDefaultPage( rreq );
-					teForm.setThemeTemplate( page.getTemplate() );
-					
-					
-				//}				
-			}
-			else
-			{
-				forward = mapping.findForward("access-denied");
-			}
-		}
-		catch (Exception e)
-		{
-            mLogger.error("ERROR in action",e);
-			throw new ServletException(e); 
-		}
-		return forward;
-	}
-
-	//-----------------------------------------------------------------------
-	/**
-	 * Load the template/theme to be previewed.  The template must be stashed
-	 * in PreviewResourceLoader so that PreviewServlet can find it.
-     * 
-     * @param mapping Struts action mapping.
-     * @param form Theme editor form bean.
-     * @param request Servlet request.
-     * @param response Servlet response.
-     * @return Forward to edit-website page.
-     * @throws IOException
-     * @throws ServletException
-	 */
-	public ActionForward preview(
-		ActionMapping       mapping,
-		ActionForm          form,
-		HttpServletRequest  request,
-		HttpServletResponse response)
-		throws IOException, ServletException
-	{
-		ActionErrors errors = new ActionErrors();
-		ActionForward forward = mapping.findForward("editTheme.page");
-		try
-		{
-			RollerRequest rreq = RollerRequest.getRollerRequest(request);
-			if ( rreq.isUserAuthorizedToEdit() )
-			{
-                HttpSession session = request.getSession();
-				ThemeEditorForm teForm = (ThemeEditorForm)form;
-				
-                String theme = teForm.getThemeName();
-                ServletContext ctx = rreq.getServletContext();
-                RollerContext rollerContext =
-                    RollerContext.getRollerContext( ctx );
-                                      
-                boolean showCustom = false;
-				if ( !"Custom".equals( theme ) )
-				{
-                    // if it isn't a custom template, load it from file
-					String sb = this.readTheme(rollerContext, theme);
-					teForm.setThemeTemplate( sb );
-
-					// clear any previously set themes
-					clearThemePages(rreq, 
-						(String) session.getAttribute(LAST_THEME)); 
-						                   
-                    setThemePages(rreq, theme);
-					session.setAttribute(LAST_THEME, theme);
-				}
-                else
-                {
-                	showCustom = true;
-                    clearThemePages(rreq, 
-                        (String) session.getAttribute(LAST_THEME));
-                        
-                    session.removeAttribute(LAST_THEME);
-					//session.removeAttribute(SESSION_TEMPLATE);
-                    
-				   //UserData ud = rreq.getUser();
-				   //PreviewResourceLoader.clearAllTemplates( ud.getUserName());
-                }
-				loadThemes( rreq, errors, showCustom);
-
-				// put the template where PreviewServlet
-				// will be able to find it
-				WeblogTemplate page = getDefaultPage( rreq );			
-				PreviewResourceLoader.setTemplate(page.getId(), 
-					teForm.getThemeTemplate(), rreq.getUser().getUserName() );
-				
-				// save the template in session for later editing
-				session.setAttribute(SESSION_TEMPLATE,
-					teForm.getThemeTemplate() );
-			}
-			else
-			{
-				forward = mapping.findForward("access-denied");
-			}
-		}
-		catch (Exception e)
-		{
-            mLogger.error("ERROR in action",e);
-			throw new ServletException(e);
-		}
-		return forward;
-	}	
-
-	//-----------------------------------------------------------------------
-	/**
-	 * Save the selected Theme or edited template as the Weblog pages template.
+public class ThemeEditorAction extends DispatchAction {
+    
+    private static Log mLogger =
+            LogFactory.getFactory().getInstance(ThemeEditorAction.class);
+    
+    
+    /**
+     * Default action method.
+     */
+    public ActionForward unspecified(
+            ActionMapping       mapping,
+            ActionForm          actionForm,
+            HttpServletRequest  request,
+            HttpServletResponse response)
+            throws IOException, ServletException {
+        
+        // make "edit" our default action
+        return this.edit(mapping, actionForm, request, response);
+    }
+    
+    
+    /**
+     * Base action method.
      * 
-     * @param mapping Struts action mapping.
-     * @param form Theme editor form bean.
-     * @param request Servlet request.
-     * @param response Servlet response.
-     * @return Forward to edit-website page.
-     * @throws IOException
-     * @throws ServletException
-	 */
-	public ActionForward save(
-		ActionMapping       mapping,
-		ActionForm          form,
-		HttpServletRequest  request,
-		HttpServletResponse response)
-		throws IOException, ServletException
-	{
-		ActionErrors errors = new ActionErrors();
-		ActionForward forward = mapping.findForward("editTheme.page");
-		try
-		{
-			RollerRequest rreq = RollerRequest.getRollerRequest(request);
-			if ( rreq.isUserAuthorizedToEdit() )
-			{
-				loadThemes( rreq, errors, true);
-				ThemeEditorForm teForm = (ThemeEditorForm)form;
-                String theme = teForm.getThemeName();
-                ServletContext ctx = rreq.getServletContext();
-                RollerContext rollerContext = 
-                                RollerContext.getRollerContext( ctx );
-                	
-				// load the template either from the Form
-				// or from the disk (if its a stock Theme).
-				String template = "";
-				if ( "Custom".equals( theme ) )
-				{
-					// use the edited template
-					template = teForm.getThemeTemplate();
-				}
-				else
-				{
-					// Figure path to new user theme
-					String sb = this.readTheme(rollerContext, theme);
-					template = sb;
-				}
-
-                // we'll need the User
-                UserData ud = rreq.getUser();
-
-                // clear the places holding onto the template
-                PreviewResourceLoader.clearAllTemplates(ud.getUserName());
-                request.getSession().removeAttribute(SESSION_TEMPLATE);
-
-				// store the template in the page
-				UserManager mgr = rreq.getRoller().getUserManager();
-				WeblogTemplate page = getDefaultPage( rreq );
-
-				page.setTemplate( template );
-				mgr.storePage( page);
+     * Shows the theme chooser page with this users current theme selected.
+     **/
+    public ActionForward edit(
+            ActionMapping       mapping,
+            ActionForm          form,
+            HttpServletRequest  request,
+            HttpServletResponse response)
+            throws IOException, ServletException {
+        
+        ActionErrors errors = new ActionErrors();
+        ActionForward forward = mapping.findForward("editTheme.page");
+        try {
+            
+            RollerRequest rreq = RollerRequest.getRollerRequest(request);
+            if ( rreq.isUserAuthorizedToEdit() ) {
                 
-                saveThemePages( rreq, theme);
+                // get users current theme and our themes list
+                Roller roller = RollerFactory.getRoller();
+                ThemeManager themeMgr = roller.getThemeManager();
                 
-                // put them into the PreviewResourceLoader also
-                setThemePages(rreq, theme);
-
-				// clear the page cache
-				PageCacheFilter.removeFromCache( request, ud );
-				teForm.setThemeName("Custom");
-			}
-			else
-			{
-				forward = mapping.findForward("access-denied");
-			}
-		}
-		catch (Exception e)
-		{
-            mLogger.error("ERROR in action",e);
-			throw new ServletException(e);
-		}
-		return forward;
-	}
-	
-
-	/**
-     * Cancel choosing of theme.
-     * 
-	 * @param mapping Struts action mapping.
-	 * @param form Theme editor form bean.
-	 * @param request Servlet request.
-	 * @param response Servlet response.
-	 * @return Forward to edit-website page.
-	 * @throws IOException
-	 * @throws ServletException
-	 */
-	public ActionForward cancel(
-		ActionMapping       mapping,
-		ActionForm          form,
-		HttpServletRequest  request,
-		HttpServletResponse response)
-		throws IOException, ServletException
-	{
-		ActionForward forward = mapping.findForward("editTheme");
-		try
-		{
-			RollerRequest rreq = RollerRequest.getRollerRequest(request);
-			if ( rreq.isUserAuthorizedToEdit() )
-			{
-				// clear the page cache
-				UserData ud = rreq.getUser();
-				PageCacheFilter.removeFromCache( request, ud );
-                ThemeEditorForm teForm = (ThemeEditorForm)form;
-								
-				// clear the places holding onto the template
-				PreviewResourceLoader.clearAllTemplates( ud.getUserName() );
-				request.getSession().removeAttribute(SESSION_TEMPLATE);
-				teForm.setThemeName("Custom");
-			}
-			else
-			{
-				forward = mapping.findForward("access-denied");
-			}
-		}
-		catch (Exception e)
-		{
-            mLogger.error("ERROR in action",e);
-			throw new ServletException(e);
-		}
-		return forward;
-	}
-	
-	/**
-	 * Load the Themes from disk ONCE per user session.
-     * 
-	 * @param rreq
-	 * @param errors
-	 */
-	private void loadThemes( 
-        RollerRequest rreq, ActionErrors errors, boolean listCustom)
-	{
-		HttpSession session = rreq.getRequest().getSession(false);
-		try
-		{
-			// Figure path to new user templates
-			ServletContext ctx = rreq.getServletContext();
-			String[] themes = null;			
-			if (ctx.getAttribute("themeStore") != null)
-			{
-				themes = (String[]) ctx.getAttribute("themeStore");
-			}
-			else
-			{
-				RollerContext rollerContext = 
-								RollerContext.getRollerContext( ctx );
-				themes = rollerContext.getThemeNames();
-				ctx.setAttribute("themeStore", themes);
-			}
-			
-			// need to insert "Custom" as the top theme.
-			// "Custom" means the hand-edited template.
-			if (listCustom)
-			{
-				// probably should use arraycopy here?
-				String[] themes2 = new String[ themes.length+1 ];
-				themes2[0] = "Custom";
-				for (int i=1; i<themes2.length; i++)
-				{
-					themes2[i] = themes[i-1];
-				}
-				themes = themes2;
-			}
-			session.setAttribute( "themes", themes );
-		}
-		catch (Exception e)
-		{
-			errors.add(ActionErrors.GLOBAL_ERROR,
-				new ActionError("error.editing.user", e.toString()));
-		}
-	}
-	
-	/**
-	 * Get the Default Page for the website specified by request.
-	 * 
-	 * @param rreq
-	 * @return WeblogTemplate
-	 */
-	private WeblogTemplate getDefaultPage(RollerRequest rreq) throws RollerException
-	{
-		try
-		{
-			UserData ud = rreq.getUser();
-			UserManager mgr = rreq.getRoller().getUserManager();
-			WebsiteData wd = mgr.getWebsite( ud.getUserName() );
-			String defaultPageId = wd.getDefaultPageId();
-			return mgr.retrievePage( defaultPageId );
-		}
-		catch (Exception e)
-		{
+                String username = rreq.getUser().getUserName();
+                WebsiteData website = roller.getUserManager().getWebsite(username);
+                String currentTheme = website.getEditorTheme();
+                List themes = themeMgr.getEnabledThemesList();
+                
+                // if we allow custom themes then add it to the end of the list
+                if(RollerRuntimeConfig.getBooleanProperty("themes.customtheme.allowed"))
+                    themes.add(Theme.CUSTOM);
+                
+                // on the first pass just show a preview of the current theme
+                request.setAttribute("previewTheme", currentTheme);
+                request.setAttribute("currentTheme", currentTheme);
+                request.setAttribute("themesList", themes);
+                
+                mLogger.debug("Previewing theme "+currentTheme+" to "+username);
+                
+            } else {
+                forward = mapping.findForward("access-denied");
+            }
+            
+        } catch (Exception e) {
             mLogger.error("ERROR in action",e);
-			throw new RollerException( e );
-		}
-	}
+            throw new ServletException(e);
+        }
+        
+        return forward;
+    }
     
+
     /**
-     * Loads theme into preview resource loader.
-     * 
-     * @param rreq
-     * @param theme
-     * @throws RollerException
+     * Preview action method.
+     *
+     * Happens when the user selects a new preview theme from the dropdown menu.
+     * Shows a new preview theme.
      */
-    private void setThemePages( RollerRequest rreq, String theme )
-       throws RollerException
-    {
-        RollerContext rollerContext = 
-           RollerContext.getRollerContext(rreq.getRequest());
-           
-        try
-        {
-            UserData ud = rreq.getUser();
-            UserManager mgr = rreq.getRoller().getUserManager();
-            String username = ud.getUserName();
+    public ActionForward preview(
+            ActionMapping       mapping,
+            ActionForm          form,
+            HttpServletRequest  request,
+            HttpServletResponse response)
+            throws IOException, ServletException {
         
-            HashMap pages = rollerContext.readThemeMacros(theme);
-            Iterator iter = pages.keySet().iterator();
-            while ( iter.hasNext() )
-            {
-                String pageName = (String) iter.next();
-                String sb = (String)pages.get( pageName );
-    
-                WeblogTemplate page = mgr.getPageByName( rreq.getWebsite(), pageName );
-                if (page != null)
-                {
-                    PreviewResourceLoader.setTemplate(page.getId(),sb,username);
-                }
-                else
-                {
-                    PreviewResourceLoader.setTemplate(pageName, sb, username);
+        ActionErrors errors = new ActionErrors();
+        ActionForward forward = mapping.findForward("editTheme.page");
+        try {
+            
+            RollerRequest rreq = RollerRequest.getRollerRequest(request);
+            if ( rreq.isUserAuthorizedToEdit() ) {
+
+                // get users current theme
+                Roller roller = RollerFactory.getRoller();
+                ThemeManager themeMgr = roller.getThemeManager();
+                
+                String username = rreq.getUser().getUserName();
+                WebsiteData website = roller.getUserManager().getWebsite(username);
+                String currentTheme = website.getEditorTheme();
+                List themes = themeMgr.getEnabledThemesList();
+                
+                // if we allow custom themes then add it to the end of the list
+                if(RollerRuntimeConfig.getBooleanProperty("themes.customtheme.allowed"))
+                    themes.add(Theme.CUSTOM);
+                
+                // set the current theme in the request
+                request.setAttribute("currentTheme", currentTheme);
+                request.setAttribute("themesList", themes);
+                
+                String theme = request.getParameter("theme");
+                try {
+                    Theme previewTheme = themeMgr.getTheme(theme);
+                    
+                    if(previewTheme.isEnabled()) {
+                        // make sure the view knows what theme to preview
+                        request.setAttribute("previewTheme", previewTheme.getName());
+                    
+                        mLogger.debug("Previewing theme "+previewTheme.getName()+
+                                " to "+username);
+                    } else {
+                        request.setAttribute("previewTheme", currentTheme);
+                        errors.add(null, new ActionMessage("Theme not enabled"));
+                        saveErrors(request, errors);
+                    }
+
+                } catch(ThemeNotFoundException tnfe) {
+                    // hmm ... maybe they chose "custom"?
+                    if(theme != null && theme.equals(Theme.CUSTOM)) {
+                        request.setAttribute("previewTheme", Theme.CUSTOM);
+                    } else {
+                        // we should never get here
+                        request.setAttribute("previewTheme", currentTheme);
+                        errors.add(null, new ActionMessage("Theme not found"));
+                        saveErrors(request, errors);
+                    }
                 }
+                
+            } else {
+                forward = mapping.findForward("access-denied");
             }
-        }
-        catch (Exception e)
-        {
+            
+        } catch (Exception e) {
             mLogger.error("ERROR in action",e);
-            throw new RollerException( e );
+            throw new ServletException(e);
         }
         
+        return forward;
     }
     
+
     /**
-     * Clears users preview theme from the preview resource loader.
-     * 
-     * @param rreq
-     * @param theme
-     * @throws RollerException
+     * Save action method.
+     *
+     * Happens when the user clicks the "Save" button to set a new theme.
+     * This method simply updates the WebsiteData.editorTheme property with
+     * the value of the new theme.
      */
-    private void clearThemePages( RollerRequest rreq, String theme )
-       throws RollerException
-    {
-        if (mLogger.isDebugEnabled()) 
-        {
-            mLogger.debug("theme="+theme);
-        }
+    public ActionForward save(
+            ActionMapping       mapping,
+            ActionForm          form,
+            HttpServletRequest  request,
+            HttpServletResponse response)
+            throws IOException, ServletException {
         
-    	if (theme == null) return;
-    	
-        RollerContext rollerContext = 
-           RollerContext.getRollerContext(rreq.getRequest());
-           
-        try
-        {
-            UserData ud = rreq.getUser();
-            UserManager mgr = rreq.getRoller().getUserManager();
-            String username = ud.getUserName();
-        
-            String themeDir = rollerContext.getThemePath(theme);        
-            String[] children = RollerContext.getThemeFilenames(themeDir);
+        ActionErrors errors = new ActionErrors();
+        ActionForward forward = mapping.findForward("editTheme.page");
+        try {
             
-            // Custom theme won't have any files
-            if (children == null) return;
+            RollerRequest rreq = RollerRequest.getRollerRequest(request);
+            if ( rreq.isUserAuthorizedToEdit() ) {
+                
+                String newTheme = null;
+                
+                // lookup what theme the user wants first
+                String theme = request.getParameter("theme");
+                try {
+                    Roller roller = RollerFactory.getRoller();
+                    ThemeManager themeMgr = roller.getThemeManager();
+                    Theme previewTheme = themeMgr.getTheme(theme);
                     
-            for (int i = 0; i < children.length; i++)
-            {
-                String pageName = children[i].substring(
-                    0,children[i].length()-3);
-    
-                WeblogTemplate page = mgr.getPageByName(rreq.getWebsite(), pageName);
-                if (page != null)
-                {
-                    PreviewResourceLoader.clearTemplate( page.getId() );
+                    if(previewTheme.isEnabled()) {
+                        newTheme = previewTheme.getName();
+                    } else {
+                        errors.add(null, new ActionMessage("Theme not enabled"));
+                        saveErrors(request, errors);
+                    }
+                    
+                } catch(ThemeNotFoundException tnfe) {
+                    // possibly selected "custom"
+                    if(theme != null && theme.equals(Theme.CUSTOM)) {
+                        newTheme = Theme.CUSTOM;
+                    } else {
+                        // hmm ... that's weird
+                        mLogger.warn(tnfe);
+                        errors.add(null, new ActionMessage("Theme not found"));
+                        saveErrors(request, errors);
+                    }
                 }
-                else
-                {
-                    PreviewResourceLoader.clearTemplate( pageName );
+                
+                // update theme for website and save
+                if(newTheme != null) {
+                    try {
+                        Roller roller = RollerFactory.getRoller();
+                        String username = rreq.getUser().getUserName();
+                        WebsiteData website = roller.getUserManager().getWebsite(username);
+                        website.setEditorTheme(newTheme);
+                        website.save();
+                        
+                        mLogger.debug("Saved theme "+newTheme+
+                                " for "+username);
+                        
+                        // make sure to flush the page cache so ppl can see the change
+                        PageCacheFilter.removeFromCache(request, rreq.getUser());
+                
+                        // update complete ... now just send them back to edit
+                        return this.edit(mapping, form, request, response);
+                        
+                    } catch(RollerException re) {
+                        mLogger.error(re);
+                        errors.add(null, new ActionMessage("Error setting theme"));
+                        saveErrors(request, errors);
+                    }
                 }
+                
+                // if we got down here then there was an error :(
+                // send the user back to preview page with errors already set
+                return this.preview(mapping, form, request, response);
+                
+            } else {
+                forward = mapping.findForward("access-denied");
             }
+        } catch (Exception e) {
+            mLogger.error("ERROR in action",e);
+            throw new ServletException(e);
         }
-        catch (Exception e)
-        {
-            if (mLogger.isDebugEnabled())
-            {
-                mLogger.debug("clearThemePages error: ", e);
-            }
-            
-            throw new RollerException( e );
-        }
-        
+        return forward;
     }
+   
     
     /**
-     * Reads theme pages from disk and saves them as pages in website of
-     * the user specified by the RollerRequest. 
-     * 
-     * @param rreq Request wrapper.
-     * @param theme Name of theme to save.
-     * @throws RollerException
+     * Customize action method.
+     *
+     * Happens when a user clicks the "Customize" button on their current theme.
+     * This method copies down all the theme templates from the currently
+     * selected theme into the users custom template pages and updates the users
+     * theme to "custom".
      */
-    private void saveThemePages( RollerRequest rreq, String theme )
-       throws RollerException
-    {
-        RollerContext rollerContext = 
-           RollerContext.getRollerContext(rreq.getRequest());
-           
-        try
-        {
-            UserData ud = rreq.getUser();
-            UserManager mgr = rreq.getRoller().getUserManager();
-            String username = ud.getUserName();
-            WebsiteData website = mgr.getWebsite( username );
+    public ActionForward customize(
+            ActionMapping       mapping,
+            ActionForm          form,
+            HttpServletRequest  request,
+            HttpServletResponse response)
+            throws IOException, ServletException {
         
-            HashMap pages = rollerContext.readThemeMacros(theme);
-            Iterator iter = pages.keySet().iterator();
-            while ( iter.hasNext() )
-            {
-                String pageName = (String) iter.next();
-                String pageContent = (String)pages.get( pageName );
-    
-                WeblogTemplate page = mgr.getPageByName( rreq.getWebsite(), pageName );
-                if (page != null)
-                {
-                    // User already has page by that name, so overwrite it.
-                    page.setTemplate( pageContent );
-                }
-                else
-                {
-                    // User does not have page by that name, so create new page.
-                    page = new WeblogTemplate( null,
-                        website,         // website
-                        pageName,        // name
-                        pageName,        // description
-                        pageName,        // link
-                        pageContent,     // template
-                        new Date()       // updateTime                
-                    );
-                    mgr.storePage( page );
+        ActionErrors errors = new ActionErrors();
+        ActionForward forward = mapping.findForward("editTheme.page");
+        try {
+            
+            RollerRequest rreq = RollerRequest.getRollerRequest(request);
+            if ( rreq.isUserAuthorizedToEdit() ) {
+                
+                // copy down current theme to weblog templates
+                Roller roller = RollerFactory.getRoller();
+                ThemeManager themeMgr = roller.getThemeManager();
+                
+                String username = rreq.getUser().getUserName();
+                WebsiteData website = roller.getUserManager().getWebsite(username);
+                Theme usersTheme = themeMgr.getTheme(website.getEditorTheme());
+
+                // only if custom themes are allowed
+                if(RollerRuntimeConfig.getBooleanProperty("themes.customtheme.allowed")) {
+                    try {
+                        this.saveThemePages(website, usersTheme);
+                    } catch(RollerException re) {
+                        mLogger.error(re);
+                        errors.add(null, new ActionMessage("Error customizing theme"));
+                        saveErrors(request, errors);
+                    }
+                    
+                    // make sure to flush the page cache so ppl can see the change
+                    PageCacheFilter.removeFromCache(request, rreq.getUser());
                 }
+                
+                // just take the user back home to the edit theme page
+                return this.edit(mapping, form, request, response);
+                
+            } else {
+                forward = mapping.findForward("access-denied");
             }
-            rreq.getRoller().commit();
-        }
-        catch (Exception e)
-        {
+        } catch (Exception e) {
             mLogger.error("ERROR in action",e);
-            throw new RollerException( e );
+            throw new ServletException(e);
         }
-        
+        return forward;
     }
     
+    
     /**
-     * Read the 'Weblog.vm' file for a theme and return it as a String.
-     * 
-     * @param ctx Roller context.
-     * @param theme Name of theme.
-     * @return Theme in the form of a string.
+     * Helper method that copies down the pages from a given theme into a
+     * users weblog templates.
+     *
+     * @param rreq Request wrapper.
+     * @param theme Name of theme to save.
      * @throws RollerException
      */
-    public String readTheme(RollerContext ctx, String theme)
-        throws RollerException
-    {
-        String fileName = "Weblog.vm";
-        if (themeCache.getFromCache(theme, fileName) != null)
-        {
-            return themeCache.getFromCache(theme, fileName);
-        }
+    private void saveThemePages(WebsiteData website, Theme theme)
+        throws RollerException {
         
-        String themesDir = RollerRuntimeConfig.getProperty("users.themes.path");
-        
-        String themeFile = RollerContext.getServletContext(
-            ).getRealPath( "/" + themesDir
-            + "/" + theme + "/" + fileName );
-                        
-        // Import weblog page template from specified theme
-        StringBuffer sb = new StringBuffer();
-        BufferedReader rdr = null;
-        try
-        {
-            rdr = new BufferedReader(
-                                    new FileReader(themeFile));
-            String line = null;
-            while ( null != (line = rdr.readLine()) )
-            {
-                sb.append( line );
-                sb.append("\n");
+        try {
+            UserManager userMgr = RollerFactory.getRoller().getUserManager();
+            
+            Collection templates = theme.getTemplates();
+            Iterator iter = templates.iterator();
+            ThemeTemplate theme_template = null;
+            while ( iter.hasNext() ) {
+                theme_template = (ThemeTemplate) iter.next();
+                //String pageContent = (String) templates.get( pageName );
+                
+                WeblogTemplate template = 
+                        userMgr.getPageByName(website, theme_template.getName());
+                if (template != null) {
+                    // User already has page by that name, so overwrite it.
+                    template.setContents(theme_template.getContents());
+                    
+                    // make absolute sure that the "Weblog" template is the
+                    // default page ... it's possible for the user to change this :/
+                    if(theme_template.getName().equals("Weblog"))
+                        website.setDefaultPageId(template.getId());
+                    
+                } else {
+                    // User does not have page by that name, so create new page.
+                    template = new WeblogTemplate( null,
+                            website,                            // website
+                            theme_template.getName(),           // name
+                            theme_template.getDescription(),    // description
+                            theme_template.getName(),           // link
+                            theme_template.getContents(),       // contents
+                            new Date()                          // last mod
+                            );
+                    userMgr.storePage( template );
+                }
             }
-            themeCache.putIntoCache(theme, fileName, sb.toString());
-        }
-        catch (Exception e)
-        {
-            mLogger.error("themeFile:" + themeFile, e);
-            throw new RollerException( e );
-        }
-        finally
-        {
-            try {
-                if (rdr != null) rdr.close();
-            } catch (IOException ioe) {
-                mLogger.warn("unable to close " + themeFile);
+            
+            // now update this website's theme to custom
+            website.setEditorTheme(Theme.CUSTOM);
+            
+            // if this is the first time someone is customizing a theme then
+            // we need to set a default page
+            if(website.getDefaultPageId() == null) {
+                // we have to go back to the db to figure out the id
+                WeblogTemplate template = userMgr.getPageByName(website, "Weblog");
+                if(template != null)
+                    website.setDefaultPageId(template.getId());
             }
+            
+            // save our updated website
+            userMgr.storeWebsite(website);
+            
+            // commit?  i still don't understand when this is needed :/
+            RollerFactory.getRoller().commit();
+            
+        } catch (Exception e) {
+            mLogger.error("ERROR in action",e);
+            throw new RollerException( e );
         }
         
-        return sb.toString();
     }
 }

Modified: incubator/roller/trunk/web/website/theme-editor.jsp
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/web/website/theme-editor.jsp?rev=209360&r1=209359&r2=209360&view=diff
==============================================================================
--- incubator/roller/trunk/web/website/theme-editor.jsp (original)
+++ incubator/roller/trunk/web/website/theme-editor.jsp Tue Jul  5 17:00:35 2005
@@ -1,79 +1,116 @@
 <%@ include file="/taglibs.jsp" %><%@ include file="/theme/header.jsp"%>
 <%
+// this just makes the name for a custom theme available to our jstl EL
+String customTheme = org.roller.pojos.Theme.CUSTOM;
+request.setAttribute("customTheme", customTheme);
+boolean allowCustom = org.roller.config.RollerRuntimeConfig.getBooleanProperty("themes.customtheme.allowed");
+
 String username = "";
-try
-{
+try {
     RollerRequest rreq = RollerRequest.getRollerRequest(request);
     UserData ud = rreq.getUser();
     username = ud.getUserName();
-}
-catch (Exception e)
-{
+} catch (Exception e) {
     throw new ServletException(e);
 }
 %>
 <h1><fmt:message key="themeEditor.title" /></h1>
 
-<html:form action="/editor/themeEditor" method="post">
+<form action="themeEditor.do" method="post">
 
-<input type=hidden name="method" value='preview' />
+    <input type=hidden name="method" value="preview" />
 
-<table width="95%">
+    <table width="95%">
 
-	<tr>
-		<td>
-      <c:if test='${empty themeEditorForm.themeName || themeEditorForm.themeName == "Custom"}' >
-          <p><fmt:message key="themeEditor.yourThemeIsShownBelow" /></p>
-      </c:if>
-      <c:if test='${!empty themeEditorForm.themeName && themeEditorForm.themeName != "Custom"}' >
-          <p><fmt:message key="themeEditor.themeBelowIsCalled" /> <b><c:out value="${themeEditorForm.themeName}" /></b></p>
-          <p><fmt:message key="themeEditor.savePrompt" /></p>
-          <p><fmt:message key="themeEditor.saveWarning" /></p>  
-		      <input type="button" value='<fmt:message key="themeEditor.save" />' name="saveButton" 
-			       onclick="this.form.method.value='save';this.form.submit()" tabindex="4" />   
-		         &nbsp; &nbsp;	
-		      <input type="button" value='<fmt:message key="themeEditor.cancel" />' name="cancelButton" 
-			       onclick="this.form.method.value='cancel';this.form.submit()" tabindex="5" />
-      </c:if>			
-		</td>
-	</tr>
-
-	<tr>
-		<td>&nbsp;</td>
-	</tr>
-
-	<tr>
-		<td>	
-		    <p><fmt:message key="themeEditor.selectTheme" />:        
-		    <html:select property="themeName" size="1" onchange="this.form.submit()" >
-	          <html:options name="themes"/>
-		    </html:select>	</p>
-		</td>
-	</tr>
+        <tr>
+            <td>
+                <p>
+                    Your current theme is : <b><c:out value="${currentTheme}"/></b><br/>
+                    
+                    <c:choose>
+                        <c:when test="${currentTheme ne previewTheme}" >
+                            <fmt:message key="themeEditor.themeBelowIsCalled" /> <b><c:out value="${previewTheme}" /></b><br/>
+                            <fmt:message key="themeEditor.savePrompt" /><br/>
+                            <input type="button" 
+                                value='<fmt:message key="themeEditor.save" />'
+                                name="saveButton" 
+                                onclick="this.form.method.value='save';this.form.submit()"
+                                tabindex="4" />
+                            &nbsp;&nbsp;
+                            <input type="button" 
+                                value='<fmt:message key="themeEditor.cancel" />'
+                                name="cancelButton" 
+                                onclick="this.form.method.value='edit';this.form.submit()"
+                                tabindex="4" />
+                        </c:when>
+                        
+                        <c:when test="${currentTheme ne customTheme}">
+                          <c:if test="${allowCustom}">
+                            If you like you may customize a personal copy of this theme.<br/>
+                            <fmt:message key="themeEditor.saveWarning" /><br/>
+                            <input type="button" 
+                                value='<fmt:message key="themeEditor.customize" />'
+                                name="customizeButton" 
+                                onclick="this.form.method.value='customize';this.form.submit()"
+                                tabindex="4" />
+                          </c:if>
+                        </c:when>
+                  </c:choose>	
+		</p>
+            </td>
+        </tr>
+
+        <tr>
+            <td>&nbsp;</td>
+        </tr>
+
+        <tr>
+            <td>	
+                <p>
+                <fmt:message key="themeEditor.selectTheme" /> : 
+                <select name="theme" size="1" onchange="this.form.submit()" >
+                    <c:forEach var="themeName" items="${themesList}">
+                        <c:choose>
+                            <c:when test="${themeName eq previewTheme}">
+                                <option value="<c:out value="${themeName}"/>" selected>
+                                    <c:out value="${themeName}"/>
+                                </option>
+                            </c:when>
+                            <c:otherwise>
+                                <option value="<c:out value="${themeName}"/>">
+                                    <c:out value="${themeName}"/>
+                                </option>
+                            </c:otherwise>
+                        </c:choose>
+                    </c:forEach>
+                </select>
+                </p>
+            </td>
+        </tr>
 	
-	<tr>
-		<td>
-		<iframe name="preview" id="preview" 
-			src="<%= request.getContextPath() %>/preview/<%= username %>/" 
-			frameborder=1 width="100%" height="400" 
-			marginheight="0" marginwidth="0"></iframe>
-		</td>
-	</tr>
+        <tr>
+            <td>
+                <iframe name="preview" id="preview" 
+                src='<%= request.getContextPath() %>/preview/<%= username %>?theme=<c:out value="${previewTheme}"/>' 
+                frameborder=1 width="100%" height="400" 
+                marginheight="0" marginwidth="0"></iframe>
+            </td>
+        </tr>
 	
-</table>
+    </table>
 
-</html:form>
+</form>
 
 
 <script type="text/javascript">
-<!--
+    <!--
     function save()
     {
-        //alert(document.themeEditorForm.method.value);
-        document.themeEditorForm.method.value = "save";
-        document.themeEditorForm.submit();
+    //alert(document.themeEditorForm.method.value);
+    document.themeEditorForm.method.value = "save";
+    document.themeEditorForm.submit();
     }
-// -->
+    // -->
 </script>
 
 <%@ include file="/theme/footer.jsp"%>