001    /*
002    Copyright (c) 1996-2012, Damon Hart-Davis
003    All rights reserved.
004    
005    Redistribution and use in source and binary forms, with or without
006    modification, are permitted provided that the following conditions are
007    met:
008    
009      * Redistributions of source code must retain the above copyright
010        notice, this list of conditions and the following disclaimer.
011    
012      * Redistributions in binary form must reproduce the above copyright
013        notice, this list of conditions and the following disclaimer in the
014        documentation and/or other materials provided with the
015        distribution.
016    
017    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
018    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
019    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
020    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
021    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
022    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
024    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
025    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
027    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028    */
029    
030    package org.hd.d.pg2k.webSvr.location;
031    
032    import java.io.IOException;
033    import java.io.OutputStream;
034    
035    import javax.servlet.ServletException;
036    import javax.servlet.http.HttpServlet;
037    import javax.servlet.http.HttpServletRequest;
038    import javax.servlet.http.HttpServletResponse;
039    
040    /**Servlet to serve dynamic location thumbnail icon (ie with crosshairs).
041     * This expects two parameters, x and y, specifying the pixel coordinates
042     * of the centre of the crosshairs, ie where the exhibit is.
043     * <p>
044     * If the parameters are missing or out of bounds then the thumbnail is
045     * produced without crosshairs, possibly by redirection to the original
046     * (source) raw thumbnail image.
047     * <p>
048     * The image produced is with the type indicated by DYN_MAP_IMG_TYPE,
049     * in an efficient (small), indexed format.
050     * <p>
051     * Altered thumbnails may be cached, possibly with SoftReferences.
052     */
053    public final class LocThumbnailServlet extends HttpServlet
054        {
055        /**Respond to a GET request for the content served by this servlet.
056         *
057         * @param request The servlet request we are processing
058         * @param response The servlet response we are producing
059         *
060         * @exception java.io.IOException if an input/output error occurs
061         * @exception javax.servlet.ServletException if a servlet error occurs
062         */
063        @Override
064        public void doGet(final HttpServletRequest request,
065                          final HttpServletResponse response)
066            throws IOException, ServletException
067            {
068            doAction(request, response);
069            }
070    
071        /**Respond to a HEAD request for the content served by this servlet.
072         *
073         * @param request The servlet request we are processing
074         * @param response The servlet response we are producing
075         *
076         * @exception IOException if an input/output error occurs
077         * @exception ServletException if a servlet error occurs
078         */
079        @Override
080        public void doHead(final HttpServletRequest request,
081                           final HttpServletResponse response)
082            throws IOException, ServletException
083            {
084            doAction(request, response);
085            }
086    
087        /**Respond to a GET/HEAD request for the content served by this servlet.
088         * Returns the exhibit data, with a correct MIME type.
089         *
090         * @param request The servlet request we are processing
091         * @param response The servlet response we are producing
092         *
093         * @exception IOException if an input/output error occurs
094         * @exception ServletException if a servlet error occurs
095         */
096        public void doAction(final HttpServletRequest request,
097                             final HttpServletResponse response)
098            throws IOException, ServletException
099            {
100            try
101                {
102                // Attempt to retrieve x and y parameters.
103                // If missing or unparsable or out of range throw an Exception.
104                final int x = Integer.parseInt(request.getParameter("x"), 10);
105                final int y = Integer.parseInt(request.getParameter("y"), 10);
106                final byte[] encodedTN =
107                    LocationUtils.getLocTNWithCrosshairs(getServletContext(), x, y);
108    
109                // Set the correct MIME type.
110                response.setContentType(LocationUtils.ETP.mimeType);
111                response.setContentLength(encodedTN.length);
112    
113                // We expect this servlet to be mounted under /_static
114                // and thus to have the Expires/Cache-Control headers set automagically.
115                // If we attempt to do it here, then we may have confusion and discord.
116    
117                // If this is a HEAD, then return without providing the body.
118                if("HEAD".equalsIgnoreCase(request.getMethod()))
119                    { return; }
120    
121                // Write entire thumbnail in one go.
122                final OutputStream os = response.getOutputStream();
123                os.write(encodedTN);
124                os.flush();
125                }
126            catch(final Exception e)
127                {
128                // Redirect back to original raw thumbnail in case of error.
129                // If our result is already committed this may be messy...
130                response.reset();
131                response.resetBuffer();
132                request.getRequestDispatcher(LocationUtils.BASE_ESTD_LOC_TN_URL).
133                    forward(request, response);
134                return;
135                }
136            }
137    
138        /**Creation/load time of this class. */
139        private static final long classLoadTime = System.currentTimeMillis();
140    
141        /**Have the last-modified date be the creation time of this class. */
142        @Override protected long getLastModified(final HttpServletRequest request)
143            { return(classLoadTime); }
144    
145        /**Unique Serialisation class ID generated by http://random&#46;hd&#46;org/. */
146        private static final long serialVersionUID = -8253998074827856644L;
147        }