Modified: 
roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/ResourceServlet.java
URL: 
http://svn.apache.org/viewvc/roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/ResourceServlet.java?rev=1530968&r1=1530967&r2=1530968&view=diff
==============================================================================
--- 
roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/ResourceServlet.java
 (original)
+++ 
roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/ResourceServlet.java
 Thu Oct 10 13:19:58 2013
@@ -39,88 +39,87 @@ import org.apache.roller.weblogger.pojos
 import org.apache.roller.weblogger.ui.rendering.util.ModDateHeaderUtil;
 import org.apache.roller.weblogger.ui.rendering.util.WeblogResourceRequest;
 
-
 /**
- * Serves fixed-path files such as old-style uploads and theme resources,
- * which must exist at a fixed-path even if moved in media file folders.
+ * Serves fixed-path files such as old-style uploads and theme resources, which
+ * must exist at a fixed-path even if moved in media file folders.
  */
 public class ResourceServlet extends HttpServlet {
 
     private static Log log = LogFactory.getLog(ResourceServlet.class);
-    
-    private ServletContext context = null;
 
+    private ServletContext context = null;
 
     public void init(ServletConfig config) throws ServletException {
 
         super.init(config);
 
         log.info("Initializing ResourceServlet");
-        
+
         this.context = config.getServletContext();
     }
 
-
     /**
      * Handles requests for user uploaded resources.
      */
     public void doGet(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
-        
+
         Weblog weblog = null;
         String ctx = request.getContextPath();
         String servlet = request.getServletPath();
         String reqURI = request.getRequestURI();
-        
+
         WeblogResourceRequest resourceRequest = null;
         try {
             // parse the incoming request and extract the relevant data
             resourceRequest = new WeblogResourceRequest(request);
 
             weblog = resourceRequest.getWeblog();
-            if(weblog == null) {
-                throw new WebloggerException("unable to lookup weblog: "+
-                        resourceRequest.getWeblogHandle());
+            if (weblog == null) {
+                throw new WebloggerException("unable to lookup weblog: "
+                        + resourceRequest.getWeblogHandle());
             }
 
-        } catch(Exception e) {
+        } 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()+"]");
-        
+
+        log.debug("Resource requested [" + resourceRequest.getResourcePath()
+                + "]");
+
         long resourceLastMod = 0;
         InputStream resourceStream = null;
-        
+
         // first see if resource comes from weblog's shared theme
         try {
             WeblogTheme weblogTheme = weblog.getTheme();
-            if(weblogTheme != null) {
-                ThemeResource resource = 
weblogTheme.getResource(resourceRequest.getResourcePath());
-                if(resource != null) {
+            if (weblogTheme != null) {
+                ThemeResource resource = weblogTheme
+                        .getResource(resourceRequest.getResourcePath());
+                if (resource != null) {
                     resourceLastMod = resource.getLastModified();
                     resourceStream = resource.getInputStream();
                 }
             }
         } catch (Exception ex) {
-            // hmmm, some kind of error getting theme.  that's an error.
+            // 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) {
+        if (resourceStream == null) {
             try {
-                MediaFileManager mmgr =
-                    WebloggerFactory.getWeblogger().getMediaFileManager();
-                MediaFile mf = mmgr.getMediaFileByOriginalPath(
-                    weblog, resourceRequest.getResourcePath());
+                MediaFileManager mmgr = WebloggerFactory.getWeblogger()
+                        .getMediaFileManager();
+                MediaFile mf = mmgr.getMediaFileByOriginalPath(weblog,
+                        resourceRequest.getResourcePath());
                 resourceLastMod = mf.getLastModified();
                 resourceStream = mf.getInputStream();
-                
+
             } catch (Exception ex) {
                 // still not found? then we don't have it, 404.
                 log.debug("Unable to get resource", ex);
@@ -128,34 +127,36 @@ public class ResourceServlet extends Htt
                 return;
             }
         }
-        
+
         // Respond with 304 Not Modified if it is not modified.
-        if (ModDateHeaderUtil.respondIfNotModified(request, response, 
resourceLastMod)) {
+        if (ModDateHeaderUtil.respondIfNotModified(request, response,
+                resourceLastMod, resourceRequest.getDeviceType())) {
             return;
         } else {
             // set last-modified date
-            ModDateHeaderUtil.setLastModifiedHeader(response, resourceLastMod);
+            ModDateHeaderUtil.setLastModifiedHeader(response, resourceLastMod,
+                    resourceRequest.getDeviceType());
         }
-        
 
         // set the content type based on whatever is in our web.xml mime defs
-        
response.setContentType(this.context.getMimeType(resourceRequest.getResourcePath()));
-        
+        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) {
+            while ((length = resourceStream.read(buf)) > 0) {
                 out.write(buf, 0, length);
             }
-            
+
             // close output stream
             out.close();
-            
+
         } catch (Exception ex) {
-            if(!response.isCommitted()) {
+            if (!response.isCommitted()) {
                 response.reset();
                 
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
             }

Modified: 
roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ModDateHeaderUtil.java
URL: 
http://svn.apache.org/viewvc/roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ModDateHeaderUtil.java?rev=1530968&r1=1530967&r2=1530968&view=diff
==============================================================================
--- 
roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ModDateHeaderUtil.java
 (original)
+++ 
roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ModDateHeaderUtil.java
 Thu Oct 10 13:19:58 2013
@@ -18,76 +18,147 @@
 
 package org.apache.roller.weblogger.ui.rendering.util;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 
 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.util.DateUtil;
+import org.apache.roller.weblogger.ui.rendering.mobile.MobileDeviceRepository;
+
 /**
  * Utility class to localize the modification date header-related logic.
  */
 public class ModDateHeaderUtil {
-    private static final Log log = LogFactory.getLog(ModDateHeaderUtil.class);
 
-    // Utility class with static methods; inhibit construction
-    private ModDateHeaderUtil() {
+       private static Log log = LogFactory.getLog(ModDateHeaderUtil.class);
+
+       /**
+        * Instantiates a new mod date header util.
+        */
+       private ModDateHeaderUtil() {
+       }
+
+       /**
+        * Sets the HTTP response status to 304 (NOT MODIFIED) if the request
+        * contains an If-Modified-Since header that specifies a time that is 
at or
+        * after the time specified by the value of lastModifiedTimeMillis
+        * <em>truncated to second granularity</em>. Returns true if the 
response
+        * status was set, false if not.
+        * 
+        * @param request
+        *            the request
+        * @param response
+        *            the response
+        * @param lastModifiedTimeMillis
+        *            the last modified time millis
+        * @param deviceType
+        *            the device type. Null to ignore ie no theme device type
+        *            swithing check.
+        * 
+        * @return true if a response status was sent, false otherwise.
+        */
+       public static boolean respondIfNotModified(HttpServletRequest request,
+                       HttpServletResponse response, long 
lastModifiedTimeMillis,
+                       MobileDeviceRepository.DeviceType deviceType) {
+
+               long sinceDate = 0;
+               try {
+                       sinceDate = request.getDateHeader("If-Modified-Since");
+               } catch (IllegalArgumentException ex) {
+                       // this indicates there was some problem parsing the 
header value as
+                       // a date
+                       return false;
+               }
+
+               // truncate to seconds
+               lastModifiedTimeMillis -= (lastModifiedTimeMillis % 1000);
+
+               if (log.isDebugEnabled()) {
+                       SimpleDateFormat dateFormat = new SimpleDateFormat(
+                                       "EEE MMM dd 'at' h:mm:ss a");
+                       log.debug("since date = "
+                                       + DateUtil.format(new Date(sinceDate), 
dateFormat));
+                       log.debug("last mod date (trucated to seconds) = "
+                                       + DateUtil.format(new 
Date(lastModifiedTimeMillis),
+                                                       dateFormat));
+               }
+
+               // Set device type for device switching
+               String eTag = null;
+               if (deviceType != null) {
+                       // int code = new 
HashCodeBuilder().append(deviceType.name())
+                       // .hashCode();
+                       // eTag = String.valueOf(code);
+                       eTag = deviceType.name();
+               }
+
+               String previousToken = request.getHeader("If-None-Match");
+               if (eTag != null && previousToken != null && 
eTag.equals(previousToken)
+                               && lastModifiedTimeMillis <= sinceDate
+                               || (eTag == null || previousToken == null)
+                               && lastModifiedTimeMillis <= sinceDate) {
+
+                       if (log.isDebugEnabled())
+                               log.debug("NOT MODIFIED " + 
request.getRequestURL());
+
+                       response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+
+                       // use the same date we sent when we created the ETag 
the
+                       // first time through
+                       response.setHeader("Last-Modified",
+                                       request.getHeader("If-Modified-Since"));
+
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Set the Last-Modified header using the given time in milliseconds. 
Note
+        * that because the header has the granularity of one second, the value 
will
+        * get truncated to the nearest second that does not exceed the provided
+        * value.
+        * <p/>
+        * This will also set the Expires header to a date in the past. This 
forces
+        * clients to revalidate the cache each time.
+        * 
+        * @param response
+        *            the response
+        * @param lastModifiedTimeMillis
+        *            the last modified time millis
+        * @param deviceType
+        *            the device type. Null to ignore ie no theme device type
+        *            swithing check.
+        */
+       public static void setLastModifiedHeader(HttpServletResponse response,
+                       long lastModifiedTimeMillis,
+                       MobileDeviceRepository.DeviceType deviceType) {
+
+               // Save our device type for device switching. Must use chaching 
on
+               // headers for this to work.
+               if (deviceType != null) {
+
+                       // int code = new 
HashCodeBuilder().append(deviceType.name())
+                       // .hashCode();
+                       // String eTag = String.valueOf(code);
+
+                       String eTag = deviceType.name();
+
+                       response.setHeader("ETag", eTag);
+               }
+
+               response.setDateHeader("Last-Modified", lastModifiedTimeMillis);
+               // Force clients to revalidate each time
+               // See RFC 2616 (HTTP 1.1 spec) secs 14.21, 13.2.1
+               response.setDateHeader("Expires", 0);
+               // We may also want this (See 13.2.1 and 14.9.4)
+               // response.setHeader("Cache-Control","must-revalidate");
 
-    }
+       }
 
-    /**
-     * Sets the HTTP response status to 304 (NOT MODIFIED) if the request 
contains an
-     * If-Modified-Since header that specifies a time that is
-     * at or after the time specified by the value of lastModifiedTimeMillis
-     * <em>truncated to second granularity</em>.  Returns true if
-     * the response status was set, false if not.
-     *
-     * @param request
-     * @param response
-     * @param lastModifiedTimeMillis
-     * @return true if a response status was sent, false otherwise.
-     */
-    public static boolean respondIfNotModified(HttpServletRequest request,
-                                               HttpServletResponse response,
-                                               long lastModifiedTimeMillis) {
-        long sinceDate = 0;
-        try {
-            sinceDate = request.getDateHeader("If-Modified-Since");
-        } catch(IllegalArgumentException ex) {
-            // this indicates there was some problem parsing the header value 
as a date
-            return false;
-        }
-        
-        // truncate to seconds
-        lastModifiedTimeMillis -= (lastModifiedTimeMillis % 1000);
-        log.debug("since date = " + sinceDate);
-        log.debug("last mod date (trucated to seconds) = " + 
lastModifiedTimeMillis);
-        if (lastModifiedTimeMillis <= sinceDate) {
-            log.debug("NOT MODIFIED " + request.getRequestURL());
-            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Set the Last-Modified header using the given time in milliseconds.  
Note that because the
-     * header has the granularity of one second, the value will get truncated 
to the nearest second that does not
-     * exceed the provided value.
-     * <p/>
-     * This will also set the Expires header to a date in the past.  This 
forces clients to revalidate the cache each
-     * time.
-     *
-     * @param response
-     * @param lastModifiedTimeMillis
-     */
-    public static void setLastModifiedHeader(HttpServletResponse response, 
long lastModifiedTimeMillis) {
-        response.setDateHeader("Last-Modified", lastModifiedTimeMillis);
-        // Force clients to revalidate each time
-        // See RFC 2616 (HTTP 1.1 spec) secs 14.21, 13.2.1
-        response.setDateHeader("Expires", 0);
-        // We may also want this (See 13.2.1 and 14.9.4)
-        // response.setHeader("Cache-Control","must-revalidate");
-    }
 }


Reply via email to