com.octo.captcha.image.ImageCaptcha Maven / Gradle / Ivy
/*
* JCaptcha, the open source java framework for captcha definition and integration
* Copyright (c) 2007 jcaptcha.net. All Rights Reserved.
* See the LICENSE.txt file distributed with this package.
*/
package com.octo.captcha.image;
import com.octo.captcha.Captcha;
import javax.imageio.ImageIO;
import javax.imageio.stream.MemoryCacheImageInputStream;
import javax.imageio.stream.MemoryCacheImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.IOException;
/**
*
* String question about a BufferedImage challenge. Abstract.
*
*
* @author Marc-Antoine Garrigue
* @version 1.0
*/
public abstract class ImageCaptcha implements Captcha {
/**
*
*/
private static final long serialVersionUID = 1L;
private Boolean hasChallengeBeenCalled = Boolean.FALSE;
protected String question;
protected String response;
// protected String textChallenge;
protected transient BufferedImage challenge;
protected ImageCaptcha(String question, BufferedImage challenge) {
this.challenge = challenge;
this.question = question;
}
protected ImageCaptcha(String question, String response, BufferedImage challenge) {
this.challenge = challenge;
this.question = question;
this.response = response;
}
/**
* Accessor captcha question
*
* @return the question
*/
public final String getQuestion() {
return question;
}
public final String getResponse() {
return response;
}
public final String getTextChallenge() {
return response;
}
/**
* @return the challenge
*/
public final Object getChallenge() {
return getImageChallenge();
}
/**
* @return the image challenge
*/
public final BufferedImage getImageChallenge() {
hasChallengeBeenCalled = Boolean.TRUE;
return challenge;
}
/**
* Dispose the challenge, once this method is call the getChallenge method
* will return null.
* It has been added for technical reasons : a captcha is always used in a
* two step fashion
* First submit the challenge, and then wait until the response arrives.
* It had been asked to have a method to dispose the challenge that is no
* longer used after being dipslayed. So here it is!
*/
public final void disposeChallenge() {
this.challenge = null;
}
/**
* This method should return true if the getChalenge method has been called
* (has been added in order to properly manage the captcha state.
*
* @return true if getChallenge has been called false otherwise.
*/
public Boolean hasGetChalengeBeenCalled() {
return hasChallengeBeenCalled;
}
/**
* This method have to be implemented in order to serialize the image
* challenge to JPEG format
*
* @param out
* The target outputStream in which the captcha will be
* serialized
* @throws IOException
*/
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
// Serialize captcha fields with defaut method
out.defaultWriteObject();
// If the challenge has not been disposed
if (this.challenge != null) {
// use png encoding
ImageIO.write(this.challenge, "png", new MemoryCacheImageOutputStream(out));
}
}
/**
* This method have to be implemented in order to unserialize the image
* challenge from JPEG format
*
* @param in
* The source inputStream from which the captcha will be
* unserialized
* @throws IOException
* @throws ClassNotFoundException
*/
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
// UnSerialize captcha fields with default method
in.defaultReadObject();
try {
this.challenge = ImageIO.read(new MemoryCacheImageInputStream(in));
}
catch (IOException e) {
if (!hasChallengeBeenCalled.booleanValue()) {
// If the getChallenge method has not been called the challenge
// should be available for unmarhslling.
// In this case, the thrown Exception is not related to the
// dispose status
throw e;
}
}
}
}