Clover coverage report -
Coverage timestamp: Fri Nov 19 2004 13:41:51 PST
file stats: LOC: 190   Methods: 9
NCLOC: 164   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ImageServlet.java 0% 0% 0% 0%
coverage
 1    package photospace.web;
 2   
 3    import java.awt.*;
 4    import java.awt.image.*;
 5    import java.io.*;
 6    import java.text.*;
 7    import java.util.*;
 8    import javax.servlet.*;
 9    import javax.servlet.http.*;
 10    import org.apache.commons.logging.*;
 11    import org.springframework.context.*;
 12    import org.springframework.web.context.support.*;
 13    import com.sun.image.codec.jpeg.*;
 14    import photospace.graphics.*;
 15    import photospace.vfs.*;
 16   
 17    public class ImageServlet
 18    extends HttpServlet
 19    {
 20    private static final Log log = LogFactory.getLog(ImageServlet.class);
 21   
 22    private static final int inputBufferSize = 2048;
 23    private static final int outputBufferSize = 2048;
 24    private static final SimpleDateFormat format;
 25    static
 26    {
 27  0 format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
 28  0 format.setTimeZone(TimeZone.getTimeZone("GMT"));
 29    }
 30   
 31    private FileSystem filesystem;
 32    private int expires = 30;
 33    private ImageCache images;
 34   
 35  0 public void init(ServletConfig config) throws ServletException
 36    {
 37  0 super.init(config);
 38   
 39  0 if (config.getInitParameter("expires-seconds") != null)
 40  0 expires = Integer.parseInt(config.getInitParameter("expires-seconds"));
 41   
 42  0 ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
 43  0 if (context != null)
 44    {
 45  0 filesystem = (FileSystem) context.getBean("filesystem");
 46  0 images = (ImageCache) context.getBean("imageCache");
 47    }
 48    else
 49    {
 50  0 filesystem = new FileSystemImpl();
 51  0 try
 52    {
 53  0 filesystem.setRoot(new File(config.getServletContext().getRealPath("/")));
 54    }
 55    catch (IOException e)
 56    {
 57  0 throw new ServletException(e);
 58    }
 59  0 images = new ImageCache();
 60  0 images.setRoot(new File(System.getProperty("java.io.tmpdir")));
 61    }
 62    }
 63   
 64  0 public void doGet(HttpServletRequest request, HttpServletResponse response)
 65    throws ServletException, IOException
 66    {
 67  0 String path = request.getPathInfo();
 68   
 69  0 if (path == null)
 70    {
 71  0 sendNotFound(response, path);
 72  0 return;
 73    }
 74   
 75   
 76  0 File file;
 77  0 try
 78    {
 79  0 file = filesystem.getAsset(path);
 80    }
 81    catch (FileNotFoundException e)
 82    {
 83  0 sendNotFound(response, path);
 84  0 return;
 85    }
 86   
 87  0 String lastModified = format.format(new Date(file.lastModified()));
 88  0 String ifModified = request.getHeader("If-Modified-Since");
 89  0 if (ifModified != null && ifModified.startsWith(lastModified))
 90    {
 91  0 if (log.isDebugEnabled()) log.debug("Sending 403 for " + file);
 92  0 response.setHeader("Expires", getExpires());
 93  0 response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
 94  0 return;
 95    }
 96   
 97  0 String contentType = getServletContext().getMimeType(file.getPath());
 98  0 response.setContentType(contentType);
 99  0 response.setHeader("Last-Modified", lastModified);
 100  0 response.setHeader("Expires", getExpires());
 101   
 102  0 if (log.isDebugEnabled()) log.debug("Serving " + file + " for " + request.getQueryString());
 103   
 104  0 int width = -1;
 105  0 int height = -1;
 106  0 if (!isEmpty(request.getParameter("w"))) width = (int) Double.parseDouble(request.getParameter("w"));
 107  0 if (!isEmpty(request.getParameter("h"))) height = (int) Double.parseDouble(request.getParameter("h"));
 108  0 if (width > 0 || height > 0)
 109    {
 110  0 Transform transform = new Transform(new Dimension(width, height), request.getParameter("scale"));
 111   
 112  0 File cached = images.cachedFile(path, transform);
 113  0 if (cached.exists() && cached.lastModified() >= file.lastModified())
 114    {
 115  0 log.debug("Using cached file " + cached);
 116  0 sendFile(response, cached);
 117  0 return;
 118    }
 119   
 120  0 synchronized (this.getClass())
 121    {
 122  0 BufferedImage image = images.scale(Sampler.read(file), path, transform);
 123   
 124  0 response.setContentLength(Sampler.getBytes(image).length);
 125  0 write(image, response.getOutputStream());
 126    }
 127    }
 128    else
 129    {
 130  0 sendFile(response, file);
 131    }
 132    }
 133   
 134  0 private void sendFile(HttpServletResponse response, File file)
 135    throws IOException
 136    {
 137  0 response.setContentLength((int) file.length());
 138  0 write(file, response.getOutputStream());
 139    }
 140   
 141  0 private boolean isEmpty(String s)
 142    {
 143  0 return s == null || "".equals(s);
 144    }
 145   
 146  0 private String getExpires()
 147    {
 148  0 return format.format(new Date(new Date().getTime() + expires * 1000));
 149    }
 150   
 151  0 private void write(BufferedImage image, OutputStream out) throws IOException
 152    {
 153  0 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
 154  0 encoder.encode(image);
 155  0 out.close();
 156    }
 157   
 158  0 private void write(File file, OutputStream out) throws IOException
 159    {
 160  0 InputStream in = new BufferedInputStream(new FileInputStream(file));
 161  0 write(in, out);
 162    }
 163   
 164  0 public static void write(InputStream in, OutputStream out) throws IOException
 165    {
 166  0 byte buffer[] = new byte[inputBufferSize];
 167  0 int len = buffer.length;
 168   
 169  0 try
 170    {
 171  0 while (true)
 172    {
 173  0 len = in.read(buffer);
 174  0 if (len == -1) break;
 175  0 out.write(buffer, 0, len);
 176    }
 177    }
 178    finally
 179    {
 180  0 try { in.close(); }
 181  0 finally { out.close(); }
 182    }
 183    }
 184   
 185  0 private void sendNotFound(HttpServletResponse response, String path) throws IOException
 186    {
 187  0 response.sendError(HttpServletResponse.SC_NOT_FOUND, path + " is not an existing photo");
 188  0 return;
 189    }
 190    }