001    // Copyright 2011 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 java.awt.image.BufferedImage;
018    import java.io.IOException;
019    import java.io.OutputStream;
020    
021    import javax.imageio.ImageIO;
022    
023    import org.apache.tapestry5.ComponentResources;
024    import org.apache.tapestry5.Link;
025    import org.apache.tapestry5.MarkupWriter;
026    import org.apache.tapestry5.annotations.Persist;
027    import org.apache.tapestry5.annotations.SupportsInformalParameters;
028    import org.apache.tapestry5.ioc.annotations.Inject;
029    import org.apache.tapestry5.services.Response;
030    
031    import org.apache.tapestry5.kaptcha.services.KaptchaProducer;
032    
033    /**
034     * Part of a Captcha based authentication scheme; a KaptchaImage generates a new
035     * text image whenever it <em>renders</em> and can provide the previously
036     * rendred text subsequently (it is stored persistently in the session).
037     * <p>
038     * The component renders an &lt;img&gt; tag, including width and height attributes. Other attributes
039     * come from informal parameters.
040     *
041     * @since 5.3
042     */
043    @SupportsInformalParameters
044    public class KaptchaImage
045    {
046    
047        @Persist
048        private String captchaText;
049    
050        @Inject
051        private KaptchaProducer producer;
052    
053        @Inject
054        private ComponentResources resources;
055    
056        @Inject
057        private Response response;
058    
059        public String getCaptchaText()
060        {
061            return captchaText;
062        }
063    
064        void setupRender()
065        {
066            captchaText = producer.createText();
067        }
068    
069        boolean beginRender(MarkupWriter writer)
070        {
071            Link link = resources.createEventLink("image");
072    
073            writer.element("img",
074    
075            "src", link.toURI(),
076    
077            "width", producer.getWidth(),
078    
079            "height", producer.getHeight());
080    
081            resources.renderInformalParameters(writer);
082    
083            writer.end();
084    
085            return false;
086        }
087    
088        void onImage() throws IOException
089        {
090            BufferedImage image = producer.createImage(captchaText);
091    
092            response.setDateHeader("Expires", 0);
093            // Set standard HTTP/1.1 no-cache headers.
094            response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
095            // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
096            response.setHeader("Cache-Control", "post-check=0, pre-check=0");
097            // Set standard HTTP/1.0 no-cache header.
098            response.setHeader("Pragma", "no-cache");
099    
100            OutputStream stream = response.getOutputStream("image/jpeg");
101    
102            ImageIO.write(image, "jpg", stream);
103    
104            stream.flush();
105    
106            stream.close();
107        }
108    }