001    // Copyright 2011, 2012 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    // http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry5.kaptcha.components;
016    
017    import org.apache.tapestry5.ComponentResources;
018    import org.apache.tapestry5.Link;
019    import org.apache.tapestry5.MarkupWriter;
020    import org.apache.tapestry5.annotations.Persist;
021    import org.apache.tapestry5.annotations.SupportsInformalParameters;
022    import org.apache.tapestry5.ioc.annotations.Inject;
023    import org.apache.tapestry5.kaptcha.services.KaptchaProducer;
024    import org.apache.tapestry5.services.Response;
025    
026    import javax.imageio.ImageIO;
027    import java.awt.image.BufferedImage;
028    import java.io.IOException;
029    import java.io.OutputStream;
030    
031    /**
032     * Part of a Captcha based authentication scheme; a KaptchaImage generates a new
033     * text image whenever it <em>renders</em> and can provide the previously
034     * rendered text subsequently (it is stored persistently in the session).
035     * <p/>
036     * The component renders an {@code <img>} tag, including width and height attributes. Other attributes
037     * come from informal parameters.
038     *
039     * @tapestrydoc
040     * @since 5.3
041     */
042    @SupportsInformalParameters
043    public class KaptchaImage
044    {
045    
046        @Persist
047        private String captchaText;
048    
049        @Inject
050        private KaptchaProducer producer;
051    
052        @Inject
053        private ComponentResources resources;
054    
055        @Inject
056        private Response response;
057    
058        public String getCaptchaText()
059        {
060            return captchaText;
061        }
062    
063        void setupRender()
064        {
065            captchaText = producer.createText();
066        }
067    
068        boolean beginRender(MarkupWriter writer)
069        {
070            Link link = resources.createEventLink("image");
071    
072            writer.element("img",
073    
074                    "src", link.toURI(),
075    
076                    "width", producer.getWidth(),
077    
078                    "height", producer.getHeight());
079    
080            resources.renderInformalParameters(writer);
081    
082            writer.end();
083    
084            return false;
085        }
086    
087        void onImage() throws IOException
088        {
089            BufferedImage image = producer.createImage(captchaText);
090    
091            response.setDateHeader("Expires", 0);
092            // Set standard HTTP/1.1 no-cache headers.
093            response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
094            // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
095            response.setHeader("Cache-Control", "post-check=0, pre-check=0");
096            // Set standard HTTP/1.0 no-cache header.
097            response.setHeader("Pragma", "no-cache");
098    
099            OutputStream stream = response.getOutputStream("image/jpeg");
100    
101            ImageIO.write(image, "jpg", stream);
102    
103            stream.flush();
104    
105            stream.close();
106        }
107    }