You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2014/01/09 14:03:50 UTC

[04/50] [abbrv] git commit: WICKET-5445 Make CaptchaImageResource easier to extend and reuse

WICKET-5445 Make CaptchaImageResource easier to extend and reuse

Make CaptchaImageResource easier to extend and add demos with Kaptcha and Cage libraries

(cherry picked from commit 853b568a5e75305722e487b85082eb923f8b6d31)


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/df6e151a
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/df6e151a
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/df6e151a

Branch: refs/heads/sandbox/WICKET-4686
Commit: df6e151aa4695315774130fd182ccbdf870cd50b
Parents: 1945ffd
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
Authored: Mon Dec 16 14:21:38 2013 +0200
Committer: Martin Tzvetanov Grigorov <mg...@apache.org>
Committed: Mon Dec 16 14:27:28 2013 +0200

----------------------------------------------------------------------
 wicket-examples/pom.xml                         |  10 ++
 .../examples/captcha/AbstractCaptchaForm.html   |  23 ++++
 .../examples/captcha/AbstractCaptchaForm.java   | 112 +++++++++++++++++++
 .../wicket/examples/captcha/CageForm.java       |  57 ++++++++++
 .../apache/wicket/examples/captcha/Captcha.html |  28 +++--
 .../apache/wicket/examples/captcha/Captcha.java | 106 ++----------------
 .../wicket/examples/captcha/CaptchaForm.java    |  53 +++++++++
 .../wicket/examples/captcha/KaptchaForm.java    |  63 +++++++++++
 .../html/captcha/CaptchaImageResource.java      |   8 +-
 9 files changed, 346 insertions(+), 114 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/df6e151a/wicket-examples/pom.xml
----------------------------------------------------------------------
diff --git a/wicket-examples/pom.xml b/wicket-examples/pom.xml
index b1f2631..4f8c206 100644
--- a/wicket-examples/pom.xml
+++ b/wicket-examples/pom.xml
@@ -153,6 +153,16 @@
 			<scope>provided</scope>
 			<version>2.2.1</version>
 		</dependency>
+		<dependency>
+			<groupId>com.github.axet</groupId>
+			<artifactId>kaptcha</artifactId>
+			<version>0.0.9</version>
+		</dependency>
+		<dependency>
+			<groupId>com.github.cage</groupId>
+			<artifactId>cage</artifactId>
+			<version>1.0</version>
+		</dependency>
 	</dependencies>
 	<build>
 		<resources>

http://git-wip-us.apache.org/repos/asf/wicket/blob/df6e151a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/AbstractCaptchaForm.html
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/AbstractCaptchaForm.html b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/AbstractCaptchaForm.html
new file mode 100644
index 0000000..504d52f
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/AbstractCaptchaForm.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html xmlns:wicket="http://wicket.apache.org">
+<body>
+
+    <wicket:panel>
+        <form wicket:id="form">
+            <p>
+                <img wicket:id="image" />
+                <a wicket:id="changeLink">change</a>
+            </p>
+            <p>
+                Please replicate the text you see above
+                <br />
+                <input wicket:id="text" type="text" size="40" />
+                <input type="submit" value="submit" />
+            </p>
+
+            <div wicket:id="feedback"></div>
+        </form>
+    </wicket:panel>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/wicket/blob/df6e151a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/AbstractCaptchaForm.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/AbstractCaptchaForm.java b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/AbstractCaptchaForm.java
new file mode 100644
index 0000000..6f85c30
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/AbstractCaptchaForm.java
@@ -0,0 +1,112 @@
+/*
+ * 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.wicket.examples.captcha;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.extensions.markup.html.captcha.CaptchaImageResource;
+import org.apache.wicket.feedback.ContainerFeedbackMessageFilter;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.RequiredTextField;
+import org.apache.wicket.markup.html.image.Image;
+import org.apache.wicket.markup.html.panel.FeedbackPanel;
+import org.apache.wicket.markup.html.panel.GenericPanel;
+import org.apache.wicket.model.PropertyModel;
+
+public abstract class AbstractCaptchaForm<T> extends GenericPanel<T>
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * The generated random text;
+	 */
+	protected String randomText;
+
+	/**
+	 * The text provided by the user
+	 */
+	private String captchaText;
+
+	private final CaptchaImageResource captchaImageResource;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param id
+	 *          The component id
+	 */
+	public AbstractCaptchaForm(String id)
+	{
+		super(id);
+
+		Form<T> form = new Form<T>("form")
+		{
+			@Override
+			public void onSubmit()
+			{
+				if (!randomText.equals(captchaText))
+				{
+					error("Captcha text '" + captchaText + "' is wrong.\n" +
+							"Correct text was: " + randomText);
+				}
+				else
+				{
+					info("Success!");
+				}
+
+				// force redrawing
+				captchaImageResource.invalidate();
+			}
+		};
+		add(form);
+
+		final FeedbackPanel feedback = new FeedbackPanel("feedback",
+				new ContainerFeedbackMessageFilter(AbstractCaptchaForm.this));
+		form.add(feedback);
+
+		captchaImageResource = createCaptchImageResource();
+		final Image captchaImage = new Image("image", captchaImageResource);
+		captchaImage.setOutputMarkupId(true);
+		form.add(captchaImage);
+
+		AjaxLink<Void> changeCaptchaLink = new AjaxLink<Void>("changeLink")
+		{
+			@Override
+			public void onClick(AjaxRequestTarget target)
+			{
+				captchaImageResource.invalidate();
+				target.add(captchaImage);
+			}
+		};
+		form.add(changeCaptchaLink);
+
+		form.add(new RequiredTextField<String>("text",
+				new PropertyModel<String>(AbstractCaptchaForm.this, "captchaText"), String.class)
+		{
+			@Override
+			protected final void onComponentTag(final ComponentTag tag)
+			{
+				super.onComponentTag(tag);
+				// clear the field after each render
+				tag.put("value", "");
+			}
+		});
+	}
+
+	protected abstract CaptchaImageResource createCaptchImageResource();
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/df6e151a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/CageForm.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/CageForm.java b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/CageForm.java
new file mode 100644
index 0000000..7517326
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/CageForm.java
@@ -0,0 +1,57 @@
+/*
+ * 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.wicket.examples.captcha;
+
+import org.apache.wicket.extensions.markup.html.captcha.CaptchaImageResource;
+
+import com.github.cage.Cage;
+import com.github.cage.GCage;
+
+/**
+ * A demo form that shows how to use <a href="https://github.com/akiraly/cage">Cage</a>
+ * library
+ */
+public class CageForm<T> extends AbstractCaptchaForm<T>
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param id
+	 *          The component id
+	 */
+	public CageForm(String id)
+	{
+		super(id);
+	}
+
+	@Override
+	protected CaptchaImageResource createCaptchImageResource()
+	{
+		return new CaptchaImageResource()
+		{
+			@Override
+			protected byte[] render()
+			{
+				randomText = Captcha.randomString(6, 8);
+				Cage cage = new GCage();
+				return cage.draw(randomText);
+			}
+		};
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/df6e151a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/Captcha.html
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/Captcha.html b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/Captcha.html
index 057b990..49daadc 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/Captcha.html
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/Captcha.html
@@ -9,20 +9,18 @@
 	<body>
 		<span wicket:id="mainNavigation" />
 
-		<form wicket:id="captchaForm">
-			<p>
-				<img wicket:id="captchaImage" />
-				<a wicket:id="changeCaptcha">change</a>
-			</p>
-			<p>
-				Please replicate the text you see above
-				<br />
-				<input wicket:id="captchaText" type="text" size="40" />
-				<input type="submit" value="submit" />
-			</p>
-		</form>
-		<p>
-			<span wicket:id="feedback">[feedback is rendered here]</span>
-		</p>
+		<h3>Demo of Wicket's default: <em>org.apache.wicket.extensions.markup.html.captcha.CaptchaImageResource</em> </h3>
+		<wicket:container wicket:id="wicket"></wicket:container>
+
+		<hr/>
+
+		<h3>Demo using <a href="https://github.com/axet/kaptcha">Kaptcha</a> library</h3>
+		<wicket:container wicket:id="kaptcha"></wicket:container>
+
+		<hr/>
+
+		<h3>Demo using <a href="https://github.com/akiraly/cage">Cage</a> library</h3>
+		<wicket:container wicket:id="cage"></wicket:container>
+
 	</body>
 </html>

http://git-wip-us.apache.org/repos/asf/wicket/blob/df6e151a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/Captcha.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/Captcha.java b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/Captcha.java
index d1217ac..757920d 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/Captcha.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/Captcha.java
@@ -16,18 +16,7 @@
  */
 package org.apache.wicket.examples.captcha;
 
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.examples.WicketExamplePage;
-import org.apache.wicket.extensions.markup.html.captcha.CaptchaImageResource;
-import org.apache.wicket.markup.ComponentTag;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.form.RequiredTextField;
-import org.apache.wicket.markup.html.image.Image;
-import org.apache.wicket.markup.html.panel.FeedbackPanel;
-import org.apache.wicket.model.PropertyModel;
-import org.apache.wicket.util.value.ValueMap;
-
 
 /**
  * Captcha example page.
@@ -36,79 +25,26 @@ import org.apache.wicket.util.value.ValueMap;
  */
 public class Captcha extends WicketExamplePage
 {
-	private final class CaptchaForm<T> extends Form<T>
-	{
-		private static final long serialVersionUID = 1L;
-
-		private final CaptchaImageResource captchaImageResource;
-
-		/**
-		 * Construct.
-		 * 
-		 * @param id
-		 */
-		public CaptchaForm(String id)
-		{
-			super(id);
-
-			captchaImageResource = new CaptchaImageResource(imagePass);
-			final Image captchaImage = new Image("captchaImage", captchaImageResource);
-			captchaImage.setOutputMarkupId(true);
-			add(captchaImage);
-
-			AjaxLink<Void> changeCaptchaLink = new AjaxLink<Void>("changeCaptcha")
-			{
-				@Override
-				public void onClick(AjaxRequestTarget target)
-				{
-					captchaImageResource.invalidate();
-					target.add(captchaImage);
-				}
-			};
-			add(changeCaptchaLink);
+	private static final long serialVersionUID = 1L;
 
-			add(new RequiredTextField<String>("captchaText", new PropertyModel<String>(properties,
-				"captchaText"), String.class)
-			{
-				@Override
-				protected final void onComponentTag(final ComponentTag tag)
-				{
-					super.onComponentTag(tag);
-					// clear the field after each render
-					tag.put("value", "");
-				}
-			});
-		}
+	/**
+	 * Constructor.
+	 */
+	public Captcha()
+	{
+		add(new CaptchaForm<Void>("wicket"));
 
-		/**
-		 * @see org.apache.wicket.markup.html.form.Form#onSubmit()
-		 */
-		@Override
-		public void onSubmit()
-		{
-			if (!imagePass.equals(getCaptchaText()))
-			{
-				error("Captcha text '" + getCaptchaText() + "' is wrong.\n" +
-					"Correct text was: " + imagePass);
-			}
-			else
-			{
-				info("Success!");
-			}
+		add(new KaptchaForm<Void>("kaptcha"));
 
-			// force redrawing
-			captchaImageResource.invalidate();
-		}
+		add(new CageForm<Void>("cage"));
 	}
 
-	private static final long serialVersionUID = 1L;
-
-	private static int randomInt(int min, int max)
+	static int randomInt(int min, int max)
 	{
 		return (int)(Math.random() * (max - min) + min);
 	}
 
-	private static String randomString(int min, int max)
+	static String randomString(int min, int max)
 	{
 		int num = randomInt(min, max);
 		byte b[] = new byte[num];
@@ -116,24 +52,4 @@ public class Captcha extends WicketExamplePage
 			b[i] = (byte)randomInt('a', 'z');
 		return new String(b);
 	}
-
-	/** Random captcha password to match against. */
-	private final String imagePass = randomString(6, 8);
-
-	private final ValueMap properties = new ValueMap();
-
-	/**
-	 * Constructor.
-	 */
-	public Captcha()
-	{
-		final FeedbackPanel feedback = new FeedbackPanel("feedback");
-		add(feedback);
-		add(new CaptchaForm<>("captchaForm"));
-	}
-
-	private String getCaptchaText()
-	{
-		return properties.getString("captchaText");
-	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/df6e151a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/CaptchaForm.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/CaptchaForm.java b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/CaptchaForm.java
new file mode 100644
index 0000000..6fe4c1e
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/CaptchaForm.java
@@ -0,0 +1,53 @@
+/*
+ * 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.wicket.examples.captcha;
+
+import org.apache.wicket.extensions.markup.html.captcha.CaptchaImageResource;
+
+/**
+ * A demo form that uses Wicket's default captcha image resource
+ */
+public class CaptchaForm<T> extends AbstractCaptchaForm<T>
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Construct.
+	 *
+	 * @param id
+	 *          The component id
+	 */
+	public CaptchaForm(String id)
+	{
+		super(id);
+	}
+
+	@Override
+	protected CaptchaImageResource createCaptchImageResource()
+	{
+		return new CaptchaImageResource()
+		{
+			@Override
+			protected byte[] render()
+			{
+				randomText = Captcha.randomString(6, 8);
+				getChallengeIdModel().setObject(randomText);
+				return super.render();
+			}
+		};
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/df6e151a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/KaptchaForm.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/KaptchaForm.java b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/KaptchaForm.java
new file mode 100644
index 0000000..a3ffa3a
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/captcha/KaptchaForm.java
@@ -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.wicket.examples.captcha;
+
+import java.awt.image.BufferedImage;
+import java.util.Properties;
+
+import org.apache.wicket.extensions.markup.html.captcha.CaptchaImageResource;
+
+import com.google.code.kaptcha.impl.DefaultKaptcha;
+import com.google.code.kaptcha.util.Config;
+
+/**
+ * A demo form that shows how to use <a href="https://github.com/axet/kaptcha">Kaptcha</a>
+ * library
+ */
+public class KaptchaForm<T> extends AbstractCaptchaForm<T>
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param id
+	 *          The component id
+	 */
+	public KaptchaForm(String id)
+	{
+		super(id);
+	}
+
+	@Override
+	protected CaptchaImageResource createCaptchImageResource()
+	{
+		return new CaptchaImageResource()
+		{
+			@Override
+			protected byte[] render()
+			{
+				DefaultKaptcha kaptcha = new DefaultKaptcha();
+				Properties properties = new Properties();
+				kaptcha.setConfig(new Config(properties));
+				randomText = Captcha.randomString(6, 8);
+				BufferedImage image = kaptcha.createImage(randomText);
+				return toImageData(image);
+			}
+		};
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/df6e151a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/captcha/CaptchaImageResource.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/captcha/CaptchaImageResource.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/captcha/CaptchaImageResource.java
index b4f2853..3208116 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/captcha/CaptchaImageResource.java
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/captcha/CaptchaImageResource.java
@@ -48,14 +48,14 @@ import org.apache.wicket.util.time.Time;
  *
  * @author Joshua Perlow
  */
-public final class CaptchaImageResource extends DynamicImageResource
+public class CaptchaImageResource extends DynamicImageResource
 {
 	/**
 	 * This class is used to encapsulate all the filters that a character will get when rendered.
 	 * The changes are kept so that the size of the shapes can be properly recorded and reproduced
 	 * later, since it dynamically generates the size of the captcha image. The reason I did it this
 	 * way is because none of the JFC graphics classes are serializable, so they cannot be instance
-	 * variables here. If anyone knows a better way to do this, please let me know.
+	 * variables here.
 	 */
 	private static final class CharAttributes implements IClusterable
 	{
@@ -136,7 +136,7 @@ public final class CaptchaImageResource extends DynamicImageResource
 	private final int fontStyle;
 
 	/**
-	 * Transient image data so that image only needs to be generated once per VM
+	 * Transient image data so that image only needs to be re-generated after de-serialization
 	 */
 	private transient SoftReference<byte[]> imageData;
 
@@ -269,7 +269,7 @@ public final class CaptchaImageResource extends DynamicImageResource
 	 *
 	 * @return The image data
 	 */
-	private byte[] render()
+	protected byte[] render()
 	{
 		int width = margin * 2;
 		int height = margin * 2;