Updated Branches:
  refs/heads/master 1945ffd8d -> df6e151aa

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/master
Commit: df6e151aa4695315774130fd182ccbdf870cd50b
Parents: 1945ffd
Author: Martin Tzvetanov Grigorov <[email protected]>
Authored: Mon Dec 16 14:21:38 2013 +0200
Committer: Martin Tzvetanov Grigorov <[email protected]>
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;

Reply via email to