1
2
3
4
5
6
7 package com.octo.captcha.sound.spellfind;
8
9 import com.octo.captcha.CaptchaException;
10 import com.octo.captcha.CaptchaQuestionHelper;
11 import com.octo.captcha.component.sound.wordtosound.WordToSound;
12 import com.octo.captcha.component.word.wordgenerator.WordGenerator;
13 import com.octo.captcha.sound.SoundCaptcha;
14 import com.octo.captcha.sound.SoundCaptchaFactory;
15 import com.octo.captcha.sound.speller.SpellerSound;
16
17 import javax.sound.sampled.AudioInputStream;
18 import java.security.SecureRandom;
19 import java.util.Locale;
20 import java.util.Random;
21 import java.util.ResourceBundle;
22
23 /***
24 * <p><ul><li></li></ul></p>
25 *
26 * @author <a href="mailto:marc.antoine.garrigue@gmail.com">Marc-Antoine Garrigue</a>
27 * @version $Id: SpellFindCaptchaFactory.java 322 2007-03-26 17:45:25Z antoineveret $
28 */
29 public class SpellFindCaptchaFactory extends SoundCaptchaFactory {
30
31 private WordGenerator wordGenerator;
32
33 private WordToSound word2Sound;
34
35 private Random myRandom = new SecureRandom();
36
37
38
39
40 /***
41 * The bundle question key for CaptchaQuestionHelper
42 */
43 public static final String BUNDLE_QUESTION_KEY = SpellFindCaptchaFactory.class.getName();
44
45 /***
46 * Construct a GimpySoundFactory from a word generator component and a wordtosound component
47 */
48 public SpellFindCaptchaFactory(WordGenerator wordGenerator, WordToSound word2Sound) {
49 if (wordGenerator == null) {
50 throw new CaptchaException("Invalid configuration for a "
51 + "SpellFindCaptchaFactory : WordGenerator can't be null");
52 }
53 if (word2Sound == null) {
54 throw new CaptchaException("Invalid configuration for a "
55 + "SpellFindCaptchaFactory : Word2Sound can't be null");
56 }
57
58
59
60
61
62
63 this.wordGenerator = wordGenerator;
64 this.word2Sound = word2Sound;
65
66
67 }
68
69 public WordToSound getWordToSound() {
70 return this.word2Sound;
71 }
72
73 public WordGenerator getWordGenerator() {
74 return this.wordGenerator;
75 }
76
77 /***
78 * @return a Sound Captcha
79 */
80 public SoundCaptcha getSoundCaptcha() {
81 return getSoundCaptcha(Locale.getDefault());
82 }
83
84 /***
85 * @param locale the locale
86 * @return a localized sound captcha
87 */
88 public SoundCaptcha getSoundCaptcha(Locale locale) {
89 ResourceBundle bundle = ResourceBundle.getBundle(this.getClass().getName(), locale);
90 int length = getRandomLength().intValue();
91
92
93 StringBuffer challenge = new StringBuffer();
94 StringBuffer response = new StringBuffer();
95 for (int i = 0; i < length; i++) {
96
97 String word = this.wordGenerator.getWord(new Integer(getRandomLength().intValue()), locale);
98
99 int position = Math.abs(myRandom.nextInt() % word.length());
100
101 challenge.append(bundle.getString("number"));
102 challenge.append(" ");
103 challenge.append(position + 1);
104 challenge.append(" ");
105 challenge.append(bundle.getString("word"));
106 challenge.append(" ");
107 challenge.append(word);
108 challenge.append(" ");
109 challenge.append(length - 1 == i ? bundle.getString("end") : bundle.getString("transition"));
110
111 response.append(word.charAt(position));
112 }
113
114 AudioInputStream sound = this.word2Sound.getSound(challenge.toString(), locale);
115 SoundCaptcha soundCaptcha = new SpellerSound(getQuestion(locale), sound, response.toString());
116 return soundCaptcha;
117 }
118
119 protected String getQuestion(Locale locale) {
120 return CaptchaQuestionHelper.getQuestion(locale, BUNDLE_QUESTION_KEY);
121 }
122
123
124 protected Integer getRandomLength() {
125
126
127
128
129 Integer wordLength;
130 int range = getWordToSound().getMaxAcceptedWordLength()
131 - getWordToSound().getMinAcceptedWordLength();
132 int randomRange = range != 0 ? myRandom.nextInt(range + 1) : 0;
133 wordLength = new Integer(randomRange + getWordToSound().getMinAcceptedWordLength());
134 return wordLength;
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148
149 }