View Javadoc

1   package com.atlassian.plugin.servlet;
2   
3   import com.atlassian.plugin.Plugin;
4   import com.atlassian.plugin.elements.ResourceLocation;
5   import com.atlassian.plugin.servlet.util.LastModifiedHandler;
6   
7   import javax.servlet.http.HttpServletRequest;
8   import javax.servlet.http.HttpServletResponse;
9   import java.io.IOException;
10  import java.io.InputStream;
11  import java.io.OutputStream;
12  import java.util.Date;
13  
14  import org.apache.commons.logging.Log;
15  import org.apache.commons.logging.LogFactory;
16  import org.apache.commons.io.IOUtils;
17  import org.apache.commons.lang.StringUtils;
18  
19  abstract class AbstractDownloadableResource implements DownloadableResource
20  {
21      private static final Log log = LogFactory.getLog(AbstractDownloadableResource.class);
22  
23      protected Plugin plugin;
24      protected String extraPath;
25      protected ResourceLocation resourceLocation;
26  
27      public AbstractDownloadableResource(Plugin plugin, ResourceLocation resourceLocation, String extraPath)
28      {
29          if (extraPath != null && !"".equals(extraPath.trim()) && !resourceLocation.getLocation().endsWith("/"))
30          {
31              extraPath = "/" + extraPath;
32          }
33  
34          this.plugin = plugin;
35          this.extraPath = extraPath;
36          this.resourceLocation = resourceLocation;
37      }
38  
39      public void serveResource(HttpServletRequest request, HttpServletResponse response) throws DownloadException
40      {
41          log.debug("Serving: " + this);
42  
43          InputStream resourceStream = getResourceAsStream();
44          if (resourceStream == null)
45          {
46              log.warn("Resource not found: " + this);
47              return;
48          }
49  
50          if(StringUtils.isNotBlank(getContentType()))
51          {
52              response.setContentType(getContentType());
53          }
54  
55          OutputStream out;
56          try
57          {
58              out = response.getOutputStream();
59          }
60          catch (IOException e)
61          {
62              throw new DownloadException(e);
63          }
64  
65          try
66          {
67              IOUtils.copy(resourceStream, out);
68          }
69          catch (IOException e)
70          {
71              log.error("Error serving the requested file", e);
72          }
73          finally
74          {
75              IOUtils.closeQuietly(resourceStream);
76              try
77              {
78                  out.flush();
79              }
80              catch (IOException e)
81              {
82                  log.warn("Error flushing output stream", e);
83              }
84          }
85          log.info("Serving file done.");
86      }
87  
88      /**
89       * Checks any "If-Modified-Since" header from the request against the plugin's loading time, since plugins can't
90       * be modified after they've been loaded this is a good way to determine if a plugin resource has been modified
91       * or not.
92       *
93       * If this method returns true, don't do any more processing on the request -- the response code has already been
94       * set to "304 Not Modified" for you, and you don't need to serve the file.
95       */
96      public boolean isResourceModified(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
97      {
98          Date resourceLastModifiedDate = (plugin.getDateLoaded() == null) ? new Date() : plugin.getDateLoaded();
99          LastModifiedHandler lastModifiedHandler = new LastModifiedHandler(resourceLastModifiedDate);
100         return lastModifiedHandler.checkRequest(httpServletRequest, httpServletResponse);
101     }
102 
103     public String getContentType()
104     {
105         return resourceLocation.getContentType();
106     }
107 
108     /**
109      * Returns an {@link InputStream} to stream the resource from.
110      */
111     protected abstract InputStream getResourceAsStream();
112 
113     protected String getLocation()
114     {
115         return resourceLocation.getLocation() + extraPath;
116     }
117 
118     public String toString()
119     {
120         return "Resource: " + getLocation() + " (" + getContentType() + ")";
121     }
122 }