You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ha...@apache.org on 2008/06/09 02:23:04 UTC
svn commit: r664581 - in
/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha:
./ util/
Author: hazems
Date: Sun Jun 8 17:23:03 2008
New Revision: 664581
URL: http://svn.apache.org/viewvc?rev=664581&view=rev
Log:
Moving CAPTCHA classes to Tomahawk.
Added:
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/AbstractCAPTCHAComponent.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/CAPTCHARenderer.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAConstants.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAImageGenerator.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAResponseStream.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHATextGenerator.java
myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/ColorGenerator.java
Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/AbstractCAPTCHAComponent.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/AbstractCAPTCHAComponent.java?rev=664581&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/AbstractCAPTCHAComponent.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/AbstractCAPTCHAComponent.java Sun Jun 8 17:23:03 2008
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.captcha;
+
+import javax.faces.component.UIComponentBase;
+
+/**
+ *
+ * @JSFComponent
+ * name = "t:captcha"
+ * class = "org.apache.myfaces.custom.captcha.CAPTCHAComponent"
+ * tagClass = "org.apache.myfaces.custom.captcha.CAPTCHATag"
+ *
+ * @author Hazem Saleh
+ *
+ */
+public abstract class AbstractCAPTCHAComponent extends UIComponentBase {
+
+ public static String COMPONENT_TYPE = "org.apache.myfaces.CAPTCHA";
+ public static String COMPONENT_FAMILY = "org.apache.myfaces.CAPTCHA";
+ public static String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.CAPTCHA";
+
+ // Value binding constants
+ public static final String ATTRIBUTE_CAPTCHA_SESSION_KEY_NAME = "captchaSessionKeyName";
+ public static final String ATTRIBUTE_IMAGE_WIDTH = "imageWidth";
+ public static final String ATTRIBUTE_IMAGE_HEIGHT = "imageHeight";
+
+ /**
+ * Determines the CAPTCHA session key name.
+ *
+ * @JSFProperty
+ * @return
+ */
+ public abstract String getCaptchaSessionKeyName();
+
+ /**
+ * Integer to indicate the CAPTCHA width. default is 290.
+ *
+ * @JSFProperty
+ */
+ public abstract String getImageWidth();
+
+ /**
+ * Integer to indicate the CAPTCHA height. default is 81.
+ *
+ * @JSFProperty
+ */
+ public abstract String getImageHeight();
+
+}
Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/CAPTCHARenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/CAPTCHARenderer.java?rev=664581&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/CAPTCHARenderer.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/CAPTCHARenderer.java Sun Jun 8 17:23:03 2008
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.captcha;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.util.Map;
+
+import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.context.FacesContextFactory;
+import javax.faces.context.ResponseStream;
+import javax.faces.context.ResponseWriter;
+import javax.faces.lifecycle.Lifecycle;
+import javax.faces.lifecycle.LifecycleFactory;
+import javax.faces.render.Renderer;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.myfaces.component.html.util.HtmlComponentUtils;
+import org.apache.myfaces.component.html.util.ParameterResourceHandler;
+import org.apache.myfaces.custom.captcha.util.CAPTCHAConstants;
+import org.apache.myfaces.custom.captcha.util.CAPTCHAImageGenerator;
+import org.apache.myfaces.custom.captcha.util.CAPTCHAResponseStream;
+import org.apache.myfaces.custom.captcha.util.CAPTCHATextGenerator;
+import org.apache.myfaces.custom.captcha.util.ColorGenerator;
+import org.apache.myfaces.renderkit.html.util.AddResource;
+import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
+import org.apache.myfaces.renderkit.html.util.ResourceLoader;
+
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+/**
+ *
+ * @JSFRenderer
+ * renderKitId = "HTML_BASIC"
+ * family = "org.apache.myfaces.CAPTCHA"
+ * type = "org.apache.myfaces.CAPTCHA"
+ *
+ * @author Hazem Saleh
+ *
+ */
+public class CAPTCHARenderer extends Renderer implements ResourceLoader {
+
+ public void encodeBegin(FacesContext context, UIComponent component)
+ throws IOException {
+
+ CAPTCHAComponent captchaComponent = (CAPTCHAComponent) component;
+
+ generateImageTag(context, captchaComponent);
+ }
+
+ public void encodeEnd(FacesContext context, UIComponent component)
+ throws IOException {
+ super.encodeEnd(context, component);
+ }
+
+ /*
+ * This helper method is used for generating the img tag that will
+ * use the (AddResource) to generate the url of the generated image.
+ */
+ private void generateImageTag(FacesContext context,
+ CAPTCHAComponent component) throws IOException {
+
+ AddResource addResource;
+ ResponseWriter writer = context.getResponseWriter();
+ Map params = HtmlComponentUtils.getParameterMap(component);
+ String url;
+ String captchaSessionKeyName = component.getCaptchaSessionKeyName();
+ String width = component.getImageWidth();
+ String height = component.getImageHeight();
+
+ // determine width and height of the generated image.
+ if(width == null)
+ {
+ width = CAPTCHAConstants.DEFAULT_CAPTCHA_WIDTH + "";
+ }
+
+ if(height == null)
+ {
+ height = CAPTCHAConstants.DEFAULT_CAPTCHA_HEIGHT + "";
+ }
+
+ writer.startElement(HTML.IMG_ELEM, component);
+
+ // constructing the parameter map to be passed to the (AddResource).
+ if (captchaSessionKeyName != null)
+ {
+ params.put(CAPTCHAComponent.ATTRIBUTE_CAPTCHA_SESSION_KEY_NAME,
+ captchaSessionKeyName);
+ }
+
+ // write the url to trigger the (AddResource).
+ addResource = AddResourceFactory.getInstance(context);
+
+ url = context.getExternalContext().encodeResourceURL(
+ addResource.getResourceUri(context,
+ new ParameterResourceHandler(this.getClass(), params)));
+
+
+ writer.writeAttribute(HTML.SRC_ATTR, url, null);
+
+ // write rest of attributes.
+ writer.writeAttribute(HTML.WIDTH_ATTR, width, null);
+
+ writer.writeAttribute(HTML.HEIGHT_ATTR, height, null);
+
+ writer.endElement(HTML.IMG_ELEM);
+ }
+
+ /*
+ * This method is implemented to be called from the (AddResource).
+ * It wraps the CAPTCHA image generation.
+ */
+ public void serveResource(ServletContext servletContext,
+ HttpServletRequest request, HttpServletResponse response,
+ String resourceUri) throws IOException {
+
+ // get the FacesContext from the ServletContext.
+ FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
+ .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
+ LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
+ .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
+ Lifecycle lifecycle = lifecycleFactory.getLifecycle(HtmlComponentUtils
+ .getLifecycleId(servletContext));
+ FacesContext facesContext = facesContextFactory.getFacesContext(
+ servletContext, request, response, lifecycle);
+ facesContext.setResponseStream(new CAPTCHAResponseStream(response
+ .getOutputStream()));
+
+ // render the CAPTCHA.
+ try
+ {
+ try
+ {
+ renderCAPTCHA(facesContext);
+ }
+ catch (IOException e)
+ {
+ throw new FacesException("Could not render the CAPTCHA : "
+ + e.getMessage(), e);
+ }
+ facesContext.getResponseStream().close();
+ }
+ finally
+ {
+ facesContext.release();
+ }
+ }
+
+ /*
+ * This method is used for rendering the CAPTCHA component.
+ */
+ protected void renderCAPTCHA(FacesContext facesContext) throws IOException {
+
+ // getting CAPTCHA attributes.
+ HttpServletResponse response = (HttpServletResponse) facesContext
+ .getExternalContext().getResponse();
+ ResponseStream out = facesContext.getResponseStream();
+ Map requestMap = facesContext.getExternalContext()
+ .getRequestParameterMap();
+ HttpServletRequest request = (HttpServletRequest) facesContext
+ .getExternalContext().getRequest();
+ String captchaSessionKeyName = requestMap.get(
+ CAPTCHAComponent.ATTRIBUTE_CAPTCHA_SESSION_KEY_NAME).toString();
+
+ // construct the CAPTCHA image generator object.
+ CAPTCHAImageGenerator captchaImageGenerator = new CAPTCHAImageGenerator();
+
+ try
+ {
+ String captchaText;
+ Color endingColor = ColorGenerator.generateRandomColor(null);
+ Color startingColor = ColorGenerator.generateRandomColor(endingColor);
+
+ // Generate random CAPTCHA text.
+ captchaText = CAPTCHATextGenerator.generateRandomText();
+
+ // Generate the image, the BG color is randomized from starting to ending colors.
+ captchaImageGenerator.generateImage(response, captchaText,
+ startingColor, endingColor);
+
+ // Set the generated text in the user session.
+ request.getSession().setAttribute(captchaSessionKeyName,
+ captchaText);
+
+ }
+ finally
+ {
+ out.close();
+ facesContext.responseComplete();
+ }
+ }
+}
Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAConstants.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAConstants.java?rev=664581&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAConstants.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAConstants.java Sun Jun 8 17:23:03 2008
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.captcha.util;
+
+/**
+ * This interface holds all the CAPTCHA related constants.
+ */
+public interface CAPTCHAConstants {
+ public static final int DEFAULT_CAPTCHA_WIDTH = 290;
+ public static final int DEFAULT_CAPTCHA_HEIGHT = 81;
+ public static final double PI = 3.1415926535897932384626433832795;
+ public static final int TEXT_X_COORDINATE = 50;
+ public static final int TEXT_Y_COORDINATE = 60;
+}
Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAImageGenerator.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAImageGenerator.java?rev=664581&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAImageGenerator.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAImageGenerator.java Sun Jun 8 17:23:03 2008
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.captcha.util;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.GradientPaint;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.font.TextLayout;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.Random;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.batik.ext.awt.image.codec.PNGEncodeParam;
+import org.apache.batik.ext.awt.image.codec.PNGImageEncoder;
+
+
+/**
+ * This class is responsible for generating the CAPTCHA image.
+ */
+public class CAPTCHAImageGenerator {
+
+ //private static final Color startingColor = new Color(150, 50, 150);
+ //private static final Color endingColor = new Color(255, 255, 255);
+
+ /*
+ * A helper method to draw the captcha text on the generated image.
+ */
+ private void drawTextOnImage(Graphics2D graphics, String captchaText) {
+
+ Font font;
+ TextLayout textLayout;
+ double currentFontStatus = Math.random();
+
+ // Generate random font status.
+ if (currentFontStatus >= 0.5)
+ {
+ font = new Font("Arial", Font.PLAIN, 60);
+ }
+ else
+ {
+ font = new Font("Arial", Font.BOLD, 60);
+ }
+
+ graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ textLayout = new TextLayout(captchaText, font, graphics
+ .getFontRenderContext());
+
+ textLayout.draw(graphics, CAPTCHAConstants.TEXT_X_COORDINATE,
+ CAPTCHAConstants.TEXT_Y_COORDINATE);
+ }
+
+ /*
+ * A helper method to apply noise on the generated image.
+ */
+ private void applyNoiseOnImage(Graphics2D graphics, int bufferedImageWidth,
+ int bufferedImageHeight, Color startingColor, Color endingColor) {
+
+ // Applying shear.
+ applyShear(graphics, bufferedImageWidth, bufferedImageHeight,
+ startingColor, endingColor);
+
+ // Drawing a broken line on the image.
+ drawBrokenLineOnImage(graphics);
+ }
+
+ /*
+ * This helper method is used for applying current gradient paint to the
+ * Graphics2D object.
+ */
+ private static void applyCurrentGradientPaint(Graphics2D graphics,
+ int width, int height, Color startingColor, Color endingColor) {
+
+ GradientPaint gradientPaint = new GradientPaint(0, 0, startingColor,
+ width, height, endingColor);
+
+ graphics.setPaint(gradientPaint);
+ }
+
+
+ /**
+ * This method generates the CAPTCHA image.
+ * @param response
+ * @param captchaText
+ * @param startingColor
+ * @param endingColor
+ * @throws IOException
+ */
+ public void generateImage(HttpServletResponse response, String captchaText,
+ Color startingColor, Color endingColor) throws IOException {
+
+ BufferedImage bufferedImage;
+ Graphics2D graphics;
+ PNGEncodeParam param;
+ PNGImageEncoder captchaPNGImage;
+
+ // Create the CAPTCHA Image.
+ bufferedImage = new BufferedImage(CAPTCHAConstants.DEFAULT_CAPTCHA_WIDTH, CAPTCHAConstants.DEFAULT_CAPTCHA_HEIGHT,
+ BufferedImage.TYPE_BYTE_INDEXED);
+
+ // Setup the graphics object.
+ graphics = bufferedImage.createGraphics();
+
+ applyCurrentGradientPaint(graphics, bufferedImage.getWidth(),
+ bufferedImage.getHeight(), startingColor, endingColor);
+
+ graphics.fillRect(0, 0, bufferedImage.getWidth(), bufferedImage
+ .getHeight());
+
+ graphics.setColor(Color.black);
+
+ // Draw text on the CAPTCHA image.
+ drawTextOnImage(graphics, captchaText);
+
+ // Apply noise on the CAPTCHA image.
+ applyNoiseOnImage(graphics, bufferedImage.getWidth(), bufferedImage
+ .getHeight(), startingColor, endingColor);
+
+ // Draw the image border.
+ drawBorders(graphics, bufferedImage.getWidth(), bufferedImage
+ .getHeight());
+
+ // Set the reponse content type to jpeg.
+ response.setContentType("image/jpg");
+
+ param = PNGEncodeParam.getDefaultEncodeParam(bufferedImage);
+ captchaPNGImage = new PNGImageEncoder(response.getOutputStream(), param);
+
+ captchaPNGImage.encode(bufferedImage);
+ }
+
+ /*
+ * This helper method is used for drawing a thick line on the image.
+ */
+ private void drawThickLineOnImage(Graphics graphics, int x1, int y1,
+ int x2, int y2) {
+
+ int dX = x2 - x1;
+ int dY = y2 - y1;
+ int xPoints[] = new int[4];
+ int yPoints[] = new int[4];
+ int thickness = 2;
+
+ double lineLength = Math.sqrt(dX * dX + dY * dY);
+ double scale = (double) (thickness) / (2 * lineLength);
+ double ddx = -scale * (double) dY;
+ double ddy = scale * (double) dX;
+
+ graphics.setColor(Color.black);
+
+ ddx += (ddx > 0) ? 0.5 : -0.5;
+ ddy += (ddy > 0) ? 0.5 : -0.5;
+ dX = (int) ddx;
+ dY = (int) ddy;
+
+ xPoints[0] = x1 + dX;
+ yPoints[0] = y1 + dY;
+ xPoints[1] = x1 - dX;
+ yPoints[1] = y1 - dY;
+ xPoints[2] = x2 - dX;
+ yPoints[2] = y2 - dY;
+ xPoints[3] = x2 + dX;
+ yPoints[3] = y2 + dY;
+
+ graphics.fillPolygon(xPoints, yPoints, 4);
+ }
+
+ /*
+ * This helper method is used for drawing a broken line on the image.
+ */
+ private void drawBrokenLineOnImage(Graphics2D graphics) {
+
+ int yPoint1;
+ int yPoint2;
+ int yPoint3;
+ int yPoint4;
+ int yPoint5;
+ Random random = new Random();
+
+ // Random Y Points.
+ yPoint1 = random.nextInt(CAPTCHAConstants.DEFAULT_CAPTCHA_HEIGHT);
+ yPoint2 = random.nextInt(CAPTCHAConstants.DEFAULT_CAPTCHA_HEIGHT);
+ yPoint3 = CAPTCHAConstants.DEFAULT_CAPTCHA_HEIGHT / 2;
+ yPoint4 = random.nextInt(CAPTCHAConstants.DEFAULT_CAPTCHA_HEIGHT);
+ yPoint5 = random.nextInt(CAPTCHAConstants.DEFAULT_CAPTCHA_HEIGHT);
+
+ // Draw the random broken line.
+ drawThickLineOnImage(graphics, 0, yPoint1,
+ CAPTCHAConstants.DEFAULT_CAPTCHA_WIDTH / 4, yPoint2);
+ drawThickLineOnImage(graphics,
+ CAPTCHAConstants.DEFAULT_CAPTCHA_WIDTH / 4, yPoint2,
+ CAPTCHAConstants.DEFAULT_CAPTCHA_WIDTH / 2, yPoint3);
+ drawThickLineOnImage(graphics,
+ CAPTCHAConstants.DEFAULT_CAPTCHA_WIDTH / 2, yPoint3,
+ 3 * CAPTCHAConstants.DEFAULT_CAPTCHA_WIDTH / 4, yPoint4);
+ drawThickLineOnImage(graphics,
+ 3 * CAPTCHAConstants.DEFAULT_CAPTCHA_WIDTH / 4, yPoint4,
+ CAPTCHAConstants.DEFAULT_CAPTCHA_WIDTH, yPoint5);
+ }
+
+ /*
+ * This helper method is used for calculating the delta of the shearing
+ * equation.
+ */
+ private double getDelta(int period, double i, double phase, double frames) {
+ return (double) (period / 2)
+ * Math.sin(i / (double) period
+ + (2 * CAPTCHAConstants.PI * phase) / frames);
+ }
+
+ /*
+ * This helper method is used for applying shear on the image.
+ */
+ private void applyShear(Graphics2D graphics, int bufferedImageWidth,
+ int bufferedImageHeight, Color startingColor, Color endingColor) {
+
+ int periodValue = 20;
+ int numberOfFrames = 15;
+ int phaseNumber = 7;
+ double deltaX;
+ double deltaY;
+
+ applyCurrentGradientPaint(graphics, bufferedImageWidth,
+ bufferedImageHeight, startingColor, endingColor);
+
+ for (int i = 0; i < bufferedImageWidth; ++i)
+ {
+ deltaX = getDelta(periodValue, i, phaseNumber, numberOfFrames);
+ graphics.copyArea(i, 0, 1, bufferedImageHeight, 0, (int) deltaX);
+ graphics.drawLine(i, (int) deltaX, i, 0);
+ graphics.drawLine(i, (int) deltaX + bufferedImageHeight, i,
+ bufferedImageHeight);
+ }
+
+ for (int i = 0; i < bufferedImageHeight; ++i)
+ {
+ deltaY = getDelta(periodValue, i, phaseNumber, numberOfFrames);
+ graphics.copyArea(0, i, bufferedImageWidth, 1, (int) deltaY, 0);
+ graphics.drawLine((int) deltaY, i, 0, i);
+ graphics.drawLine((int) deltaY + bufferedImageWidth, i,
+ bufferedImageWidth, i);
+ }
+ }
+
+ /*
+ * This helper method is used for drawing the borders the image.
+ */
+ private void drawBorders(Graphics2D graphics, int width, int height) {
+ graphics.setColor(Color.black);
+
+ graphics.drawLine(0, 0, 0, width - 1);
+ graphics.drawLine(0, 0, width - 1, 0);
+ graphics.drawLine(0, height - 1, width, height - 1);
+ graphics.drawLine(width - 1, height - 1, width - 1, 0);
+ }
+
+}
Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAResponseStream.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAResponseStream.java?rev=664581&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAResponseStream.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHAResponseStream.java Sun Jun 8 17:23:03 2008
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.captcha.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import javax.faces.context.ResponseStream;
+
+/**
+ * This class is responsible for wrapping the CAPTCHA Image
+ * response stream.
+ */
+public final class CAPTCHAResponseStream extends ResponseStream {
+ private final OutputStream _out;
+
+ public CAPTCHAResponseStream(OutputStream out) {
+ _out = out;
+ }
+
+ public void close() throws IOException {
+ _out.flush();
+ _out.close();
+ }
+
+ public void flush() throws IOException {
+ _out.flush();
+ }
+
+ public void write(byte[] b, int off, int len) throws IOException {
+ _out.write(b, off, len);
+ }
+
+ public void write(byte[] b) throws IOException {
+ _out.write(b);
+ }
+
+ public void write(int b) throws IOException {
+ _out.write(b);
+ }
+}
Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHATextGenerator.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHATextGenerator.java?rev=664581&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHATextGenerator.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/CAPTCHATextGenerator.java Sun Jun 8 17:23:03 2008
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.captcha.util;
+
+import java.util.Random;
+
+/**
+ * This class is responsible for generating the
+ * CAPTCHA text.
+ */
+public class CAPTCHATextGenerator {
+
+ /* CAPTCHA possible characters */
+ private final static char[] CAPTCHA_POSSIBLE_CHARS = new char[] { 'a', 'b',
+ 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2',
+ '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+ 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
+
+ /**
+ * generateRandomText() generates the CAPTCHA text
+ * @return the random generated text.
+ */
+ public static String generateRandomText() {
+
+ int totalPossibleCharacters = CAPTCHA_POSSIBLE_CHARS.length - 1;
+ String captchaText = "";
+ Random random = new Random();
+ int captchaTextLength = 5;
+ int randomNumber = random.nextInt(10);
+
+ // Determine the CAPTCHA Length whether it is five or six.
+ if(randomNumber >= 5) {
+ captchaTextLength = 6;
+ }
+
+ // Generate the random String.
+ for (int i = 0; i < captchaTextLength; ++i) {
+ captchaText += CAPTCHA_POSSIBLE_CHARS[random
+ .nextInt(totalPossibleCharacters) + 1];
+ }
+
+ return captchaText;
+ }
+
+}
Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/ColorGenerator.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/ColorGenerator.java?rev=664581&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/ColorGenerator.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/captcha/util/ColorGenerator.java Sun Jun 8 17:23:03 2008
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.captcha.util;
+
+import java.awt.Color;
+
+/**
+ * This class is responsible for generating CAPTCHA random color...
+ */
+public class ColorGenerator {
+
+ private final static int COLOR_DEGREES = 255;
+ private final static int COLOR_GENERATOR_DELTA = 127;
+
+ /**
+ * This method is used for generating a random color.
+ * @param startFrom -> the color that we should be away from.
+ * @return the new color.
+ */
+ public static Color generateRandomColor(Color startFrom) {
+
+ /* if the startingFrom color is null, then generate a new random color. */
+ if (startFrom == null)
+ {
+ return new Color((int) (Math.random() * COLOR_DEGREES), (int) (Math
+ .random() * COLOR_DEGREES),
+ (int) (Math.random() * COLOR_DEGREES));
+ }
+
+ /* try to avoid the startFrom color. */
+ int startingRed = (startFrom.getRed() >= 128) ? 0 : 128;
+ int startingGreen = (startFrom.getGreen() >= 128) ? 0 : 128;
+ int startingBlue = (startFrom.getBlue() >= 128) ? 0 : 128;
+
+ // generate the new random colors.
+ int newRandomRed = (int) (Math.random() * (startingRed + COLOR_GENERATOR_DELTA));
+ int newRandomGreen = (int) (Math.random() * (startingGreen + COLOR_GENERATOR_DELTA));
+ int newRandomBlue = (int) (Math.random() * (startingBlue + COLOR_GENERATOR_DELTA));
+
+ /*
+ * If the newly generated color is less than the starting color
+ * then add the starting color to it.
+ */
+ if (newRandomRed < startingRed)
+ {
+ newRandomRed += startingRed;
+ }
+
+ if (newRandomGreen < startingGreen)
+ {
+ newRandomGreen += startingGreen;
+ }
+
+ if (newRandomBlue < startingBlue)
+ {
+ newRandomBlue += startingBlue;
+ }
+
+ return new Color(newRandomRed, newRandomGreen, newRandomBlue);
+ }
+}