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 2006/10/06 00:49:15 UTC

svn commit: r453415 - in /incubator/roller/trunk: src/org/apache/roller/ui/rendering/model/ src/org/apache/roller/ui/rendering/servlets/ src/org/apache/roller/ui/rendering/util/ src/org/apache/roller/util/ web/WEB-INF/classes/

Author: agilliland
Date: Thu Oct  5 15:49:14 2006
New Revision: 453415

URL: http://svn.apache.org/viewvc?view=rev&rev=453415
Log:
fix theme previewing capabilities broken by revision 453354.

1. Updated PreviewServlet to use its own set of rendering models defined by "rendering.previewModels" property.

  * added new property to roller.properties
  * updated PreviewServlet to use the new property

2. Defined a PreviewURLModel which extends existing URLModel.  This allows previews to form urls that point to different places than the "real" or "live" versions of things.

  * overrided the resource() method to provide a different url which points to a special PreviewResourceServlet.
  * added url forming logic in new methods of URLUtilites.

3. Added new PreviewResourceServlet for serving resources in preview mode.

  * defined new WeblogPreviewResourceRequest which extends WeblogResourceRequest.
  * modified a copy of ResourceServlet to be sensitive to previewing.



Added:
    incubator/roller/trunk/src/org/apache/roller/ui/rendering/model/PreviewURLModel.java
    incubator/roller/trunk/src/org/apache/roller/ui/rendering/servlets/PreviewResourceServlet.java
    incubator/roller/trunk/src/org/apache/roller/ui/rendering/util/WeblogPreviewResourceRequest.java
Modified:
    incubator/roller/trunk/src/org/apache/roller/ui/rendering/servlets/PreviewServlet.java
    incubator/roller/trunk/src/org/apache/roller/ui/rendering/util/WeblogResourceRequest.java
    incubator/roller/trunk/src/org/apache/roller/util/URLUtilities.java
    incubator/roller/trunk/web/WEB-INF/classes/roller.properties

Added: incubator/roller/trunk/src/org/apache/roller/ui/rendering/model/PreviewURLModel.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/src/org/apache/roller/ui/rendering/model/PreviewURLModel.java?view=auto&rev=453415
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/ui/rendering/model/PreviewURLModel.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/ui/rendering/model/PreviewURLModel.java Thu Oct  5 15:49:14 2006
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.ui.rendering.model;
+
+import java.util.Map;
+import org.apache.roller.RollerException;
+import org.apache.roller.pojos.WebsiteData;
+import org.apache.roller.ui.rendering.util.WeblogPreviewRequest;
+import org.apache.roller.ui.rendering.util.WeblogRequest;
+import org.apache.roller.util.URLUtilities;
+
+
+/**
+ * Special subclass of URLModel which can change some of the urls which are
+ * generated to make them work for previewing mode.
+ */
+public class PreviewURLModel extends URLModel {
+    
+    private WeblogPreviewRequest previewRequest = null;
+    private WebsiteData weblog = null;
+    private String locale = null;
+    
+    
+    public void init(Map initData) throws RollerException {
+        
+        // need a weblog request so that we can know the weblog and locale
+        WeblogRequest weblogRequest = (WeblogRequest) initData.get("weblogRequest");
+        if(weblogRequest == null) {
+            throw new RollerException("Expected 'weblogRequest' init param!");
+        }
+        
+        // PreviewURLModel only works on preview requests, so cast weblogRequest
+        // into a WeblogPreviewRequest and if it fails then throw exception
+        if(weblogRequest instanceof WeblogPreviewRequest) {
+            this.previewRequest = (WeblogPreviewRequest) weblogRequest;
+        } else {
+            throw new RollerException("weblogRequest is not a WeblogPreviewRequest."+
+                    "  PreviewURLModel only supports preview requests.");
+        }
+        
+        this.weblog = weblogRequest.getWeblog();
+        this.locale = weblogRequest.getLocale();
+        
+        super.init(initData);
+    }
+    
+    
+    /**
+     * We need resource urls to point to our custom PreviewResourceServlet
+     * because when previewing a theme the ResourceServlet has no way of
+     * knowing what theme you are previewing and thus couldn't find the
+     * resources for that theme.
+     */
+    public String resource(String filePath) {
+        return URLUtilities.getPreviewWeblogResourceURL(previewRequest.getThemeName(), weblog, filePath, true);
+    }
+    
+}

Added: incubator/roller/trunk/src/org/apache/roller/ui/rendering/servlets/PreviewResourceServlet.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/src/org/apache/roller/ui/rendering/servlets/PreviewResourceServlet.java?view=auto&rev=453415
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/ui/rendering/servlets/PreviewResourceServlet.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/ui/rendering/servlets/PreviewResourceServlet.java Thu Oct  5 15:49:14 2006
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.ui.rendering.servlets;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+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.roller.RollerException;
+import org.apache.roller.model.FileManager;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.model.ThemeManager;
+import org.apache.roller.pojos.Theme;
+import org.apache.roller.pojos.WeblogResource;
+import org.apache.roller.pojos.WebsiteData;
+import org.apache.roller.ui.rendering.util.ModDateHeaderUtil;
+import org.apache.roller.ui.rendering.util.WeblogPreviewResourceRequest;
+
+
+/**
+ * Special previewing servlet which serves files uploaded by users as well as 
+ * static resources in shared themes.  This servlet differs from the normal
+ * ResourceServlet because it can accept urls parameters which affect how it
+ * behaves which are used for previewing.
+ *
+ * @web.servlet name="PreviewResourceServlet" load-on-startup="9"
+ * @web.servlet-mapping url-pattern="/roller-ui/authoring/previewresource/*"
+ */
+public class PreviewResourceServlet extends HttpServlet {
+
+    private static Log log = LogFactory.getLog(PreviewResourceServlet.class);
+    
+    private ServletContext context = null;
+
+
+    public void init(ServletConfig config) throws ServletException {
+
+        super.init(config);
+
+        log.info("Initializing PreviewResourceServlet");
+        
+        this.context = config.getServletContext();
+    }
+
+
+    /**
+     * Handles requests for user uploaded resources.
+     */
+    public void doGet(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException {
+        
+        WebsiteData weblog = null;
+        String context = request.getContextPath();
+        String servlet = request.getServletPath();
+        String reqURI = request.getRequestURI();
+        
+        WeblogPreviewResourceRequest resourceRequest = null;
+        try {
+            // parse the incoming request and extract the relevant data
+            resourceRequest = new WeblogPreviewResourceRequest(request);
+
+            weblog = resourceRequest.getWeblog();
+            if(weblog == null) {
+                throw new RollerException("unable to lookup weblog: "+
+                        resourceRequest.getWeblogHandle());
+            }
+
+        } catch(Exception e) {
+            // invalid resource request or weblog doesn't exist
+            log.debug("error creating weblog resource request", e);
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;
+        }
+        
+        log.debug("Resource requested ["+resourceRequest.getResourcePath()+"]");
+        
+        long resourceLastMod = 0;
+        InputStream resourceStream = null;
+        
+        // first, see if we have a preview theme to operate from
+        if(resourceRequest.getThemeName() != null) {
+            Theme theme = resourceRequest.getTheme();
+            File resource = theme.getResource(resourceRequest.getResourcePath());
+            resourceLastMod = resource.lastModified();
+            resourceStream = new FileInputStream(resource);
+        }
+        
+        // second, see if resource comes from weblog's configured shared theme
+        if(resourceStream == null && !Theme.CUSTOM.equals(weblog.getEditorTheme())) {
+            try {
+                ThemeManager themeMgr = RollerFactory.getRoller().getThemeManager();
+                Theme weblogTheme = themeMgr.getTheme(weblog.getEditorTheme());
+                File resource = weblogTheme.getResource(resourceRequest.getResourcePath());
+                resourceLastMod = resource.lastModified();
+                resourceStream = new FileInputStream(resource);
+            } catch (Exception ex) {
+                // hmmm, some kind of error getting theme.  that's an error.
+                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+                return;
+            }
+        }
+        
+        // if not from theme then see if resource is in weblog's upload dir
+        if(resourceStream == null) {
+            try {
+                FileManager fileMgr = RollerFactory.getRoller().getFileManager();
+                WeblogResource resource = fileMgr.getFile(weblog, 
+                        resourceRequest.getResourcePath());
+                resourceLastMod = resource.getLastModified();
+                resourceStream = resource.getInputStream();
+            } catch (Exception ex) {
+                // still not found? then we don't have it, 404.
+                log.debug("Unable to get resource", ex);
+                response.sendError(HttpServletResponse.SC_NOT_FOUND);
+                return;
+            }
+        }
+        
+        // Respond with 304 Not Modified if it is not modified.
+        if (ModDateHeaderUtil.respondIfNotModified(request, response, resourceLastMod)) {
+            return;
+        } else {
+            // set last-modified date
+            ModDateHeaderUtil.setLastModifiedHeader(response, resourceLastMod);
+        }
+        
+
+        // set the content type based on whatever is in our web.xml mime defs
+        response.setContentType(this.context.getMimeType(resourceRequest.getResourcePath()));
+        
+        OutputStream out = null;
+        try {
+            // ok, lets serve up the file
+            byte[] buf = new byte[8192];
+            int length = 0;
+            out = response.getOutputStream();
+            while((length = resourceStream.read(buf)) > 0) {
+                out.write(buf, 0, length);
+            }
+            
+            // cleanup
+            out.close();
+            resourceStream.close();
+            
+        } catch (Exception ex) {
+            log.error("Error writing resource file", ex);
+            if(!response.isCommitted()) {
+                response.reset();
+                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            }
+        }
+
+    }
+
+}

Modified: incubator/roller/trunk/src/org/apache/roller/ui/rendering/servlets/PreviewServlet.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/src/org/apache/roller/ui/rendering/servlets/PreviewServlet.java?view=diff&rev=453415&r1=453414&r2=453415
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/ui/rendering/servlets/PreviewServlet.java (original)
+++ incubator/roller/trunk/src/org/apache/roller/ui/rendering/servlets/PreviewServlet.java Thu Oct  5 15:49:14 2006
@@ -157,12 +157,11 @@
             // populate the rendering model
             Map initData = new HashMap();
             initData.put("request", request);
-            initData.put("pageRequest", previewRequest);
             initData.put("weblogRequest", previewRequest);
             initData.put("pageContext", pageContext);
             
-            // Load models for pages
-            String pageModels = RollerConfig.getProperty("rendering.pageModels");
+            // Load models for page previewing
+            String pageModels = RollerConfig.getProperty("rendering.previewModels");
             ModelLoader.loadModels(pageModels, model, initData, true);
             
             // Load special models for site-wide blog

Added: incubator/roller/trunk/src/org/apache/roller/ui/rendering/util/WeblogPreviewResourceRequest.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/src/org/apache/roller/ui/rendering/util/WeblogPreviewResourceRequest.java?view=auto&rev=453415
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/ui/rendering/util/WeblogPreviewResourceRequest.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/ui/rendering/util/WeblogPreviewResourceRequest.java Thu Oct  5 15:49:14 2006
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.ui.rendering.util;
+
+import javax.servlet.http.HttpServletRequest;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.RollerException;
+import org.apache.roller.ThemeNotFoundException;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.model.ThemeManager;
+import org.apache.roller.pojos.Theme;
+
+
+/**
+ *
+ */
+public class WeblogPreviewResourceRequest extends WeblogResourceRequest {
+    
+    private static Log log = LogFactory.getLog(WeblogPreviewResourceRequest.class);
+    
+    private static final String PREVIEWRESOURCE_SERVLET = "/roller-ui/authoring/previewresource";
+    
+    // lightweight attributes
+    private String themeName = null;
+    
+    // heavyweight attributes
+    private Theme theme = null;
+    
+    
+    public WeblogPreviewResourceRequest() {}
+    
+    
+    public WeblogPreviewResourceRequest(HttpServletRequest request) 
+            throws InvalidRequestException {
+        
+        // let parent go first
+        super(request);
+        
+        // all we need to worry about is the query params
+        // the only param we expect is "theme"
+        if(request.getParameter("theme") != null) {
+            this.themeName = request.getParameter("theme");
+        }
+        
+        if(log.isDebugEnabled()) {
+            log.debug("theme = "+this.themeName);
+        }
+    }
+    
+    
+    boolean isValidDestination(String servlet) {
+        return (servlet != null && PREVIEWRESOURCE_SERVLET.equals(servlet));
+    }
+    
+    public String getThemeName() {
+        return themeName;
+    }
+
+    public void setThemeName(String theme) {
+        this.themeName = theme;
+    }
+    
+    // override so that previews never show login status
+    public String getAuthenticUser() {
+        return null;
+    }
+    
+    // override so that previews never show login status
+    public boolean isLoggedIn() {
+        return false;
+    }
+
+    public Theme getTheme() {
+        
+        if(theme == null && themeName != null) {
+            try {
+                ThemeManager themeMgr = RollerFactory.getRoller().getThemeManager();
+                theme = themeMgr.getTheme(themeName);
+            } catch(ThemeNotFoundException tnfe) {
+                // bogus theme specified ... don't worry about it
+            } catch(RollerException re) {
+                log.error("Error looking up theme "+themeName, re);
+            }
+        }
+        
+        return theme;
+    }
+
+    public void setTheme(Theme theme) {
+        this.theme = theme;
+    }
+}

Modified: incubator/roller/trunk/src/org/apache/roller/ui/rendering/util/WeblogResourceRequest.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/src/org/apache/roller/ui/rendering/util/WeblogResourceRequest.java?view=diff&rev=453415&r1=453414&r2=453415
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/ui/rendering/util/WeblogResourceRequest.java (original)
+++ incubator/roller/trunk/src/org/apache/roller/ui/rendering/util/WeblogResourceRequest.java Thu Oct  5 15:49:14 2006
@@ -61,8 +61,8 @@
         log.debug("parsing path "+pathInfo);
         
         // was this request bound for the resource servlet?
-        if(servlet == null || !RESOURCE_SERVLET.equals(servlet)) {
-            throw new InvalidRequestException("not a weblog resource request, "+
+        if(!isValidDestination(servlet)) {
+            throw new InvalidRequestException("invalid destination for request, "+
                     request.getRequestURL());
         }
         
@@ -97,7 +97,11 @@
             log.debug("resourcePath = "+this.resourcePath);
         }
     }
-
+    
+    boolean isValidDestination(String servlet) {
+        return (servlet != null && RESOURCE_SERVLET.equals(servlet));
+    }
+    
     public String getResourcePath() {
         return resourcePath;
     }

Modified: incubator/roller/trunk/src/org/apache/roller/util/URLUtilities.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/src/org/apache/roller/util/URLUtilities.java?view=diff&rev=453415&r1=453414&r2=453415
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/util/URLUtilities.java (original)
+++ incubator/roller/trunk/src/org/apache/roller/util/URLUtilities.java Thu Oct  5 15:49:14 2006
@@ -356,6 +356,79 @@
     
     
     /**
+     * Get root url for a given *preview* weblog.  
+     * Optionally for a certain locale.
+     */
+    public static final String getPreviewWeblogURL(String previewTheme,
+                                                   WebsiteData weblog,
+                                                   String locale,
+                                                   boolean absolute) {
+        
+        if(weblog == null) {
+            return null;
+        }
+        
+        StringBuffer url = new StringBuffer();
+        
+        if(absolute) {
+            url.append(RollerRuntimeConfig.getAbsoluteContextURL());
+        } else {
+            url.append(RollerRuntimeConfig.getRelativeContextURL());
+        }
+        
+        url.append("/roller-ui/authoring/preview/").append(weblog.getHandle()).append("/");
+        
+        if(locale != null) {
+            url.append(locale).append("/");
+        }
+        
+        Map params = new HashMap();
+        if(previewTheme != null) {
+            params.put("theme", encode(previewTheme));
+        }
+        
+        return url.toString() + getQueryString(params);
+    }
+    
+    
+    /**
+     * Get a url to a *preview* resource on a given weblog.
+     */
+    public static final String getPreviewWeblogResourceURL(String previewTheme,
+                                                           WebsiteData weblog,
+                                                           String filePath,
+                                                           boolean absolute) {
+        
+        if(weblog == null) {
+            return null;
+        }
+        
+        StringBuffer url = new StringBuffer();
+        
+        if(absolute) {
+            url.append(RollerRuntimeConfig.getAbsoluteContextURL());
+        } else {
+            url.append(RollerRuntimeConfig.getRelativeContextURL());
+        }
+        
+        url.append("/roller-ui/authoring/previewresource/").append(weblog.getHandle()).append("/");
+        
+        if(filePath.startsWith("/")) {
+            url.append(filePath.substring(1));
+        } else {
+            url.append(filePath);
+        }
+        
+        Map params = new HashMap();
+        if(previewTheme != null) {
+            params.put("theme", encode(previewTheme));
+        }
+        
+        return url.toString() + getQueryString(params);
+    }
+    
+    
+    /**
      * Compose a map of key=value params into a query string.
      */
     public static final String getQueryString(Map params) {

Modified: incubator/roller/trunk/web/WEB-INF/classes/roller.properties
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/web/WEB-INF/classes/roller.properties?view=diff&rev=453415&r1=453414&r2=453415
==============================================================================
--- incubator/roller/trunk/web/WEB-INF/classes/roller.properties (original)
+++ incubator/roller/trunk/web/WEB-INF/classes/roller.properties Thu Oct  5 15:49:14 2006
@@ -141,6 +141,17 @@
 org.apache.roller.ui.rendering.model.CalendarModel,\
 org.apache.roller.ui.rendering.model.MenuModel
 
+# Set of models to be made available for weblog page *preview* rendering
+# NOTE: this *does* have some differences between the pageModels
+rendering.previewModels=\
+org.apache.roller.ui.rendering.model.PageModel,\
+org.apache.roller.ui.rendering.model.ConfigModel,\
+org.apache.roller.ui.rendering.model.UtilitiesModel,\
+org.apache.roller.ui.rendering.model.PreviewURLModel,\
+org.apache.roller.ui.rendering.model.MessageModel,\
+org.apache.roller.ui.rendering.model.CalendarModel,\
+org.apache.roller.ui.rendering.model.MenuModel
+
 # Set of page models specifically for site-wide rendering
 rendering.siteModels=\
 org.apache.roller.ui.rendering.model.SiteModel