Updated Branches: refs/heads/wicket-6.x e594bb856 -> 853b568a5
WICKET-5445 Make CaptchaImageResource easier to extend and reuse Make CaptchaImageResource easier to extend and add demos with Kaptcha and Cage libraries Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/853b568a Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/853b568a Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/853b568a Branch: refs/heads/wicket-6.x Commit: 853b568a5e75305722e487b85082eb923f8b6d31 Parents: e594bb8 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:21:38 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 | 105 ++--------------- .../wicket/examples/captcha/CaptchaForm.java | 53 +++++++++ .../wicket/examples/captcha/KaptchaForm.java | 63 +++++++++++ .../html/captcha/CaptchaImageResource.java | 8 +- 9 files changed, 346 insertions(+), 113 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/853b568a/wicket-examples/pom.xml ---------------------------------------------------------------------- diff --git a/wicket-examples/pom.xml b/wicket-examples/pom.xml index 0763a80..2561ccb 100644 --- a/wicket-examples/pom.xml +++ b/wicket-examples/pom.xml @@ -147,6 +147,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/853b568a/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/853b568a/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/853b568a/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/853b568a/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/853b568a/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 5cf70db..0a88b33 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]; @@ -117,23 +53,4 @@ public class Captcha extends WicketExamplePage 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<Void>("captchaForm")); - } - - private String getCaptchaText() - { - return properties.getString("captchaText"); - } } http://git-wip-us.apache.org/repos/asf/wicket/blob/853b568a/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/853b568a/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/853b568a/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 93d9eb1..3ddc589 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;
