View Javadoc

1   /*
2    * JCaptcha, the open source java framework for captcha definition and integration
3    * Copyright (c)  2007 jcaptcha.net. All Rights Reserved.
4    * See the LICENSE.txt file distributed with this package.
5    */
6   
7   package com.octo.captcha.component.word.wordgenerator;
8   
9   import com.octo.captcha.CaptchaException;
10  import com.octo.captcha.component.word.DictionaryReader;
11  import com.octo.captcha.component.word.SizeSortedWordList;
12  
13  import java.util.Locale;
14  
15  /***
16   * <p>This Word Generator use a Dictionnary to compose new Words from existing words.</p> It avoid dictionnary
17   * systematic submission, and may compose words of any length.
18   *
19   * @author <a href="mailto:mag@jcaptcha.net">Marc-Antoine Garrigue</a>
20   * @version 1.0
21   */
22  public class ComposeDictionaryWordGenerator extends DictionaryWordGenerator {
23  
24      public ComposeDictionaryWordGenerator(DictionaryReader reader) {
25          super(reader);
26      }
27  
28      /***
29       * Return a word of length between min and max length according to the given locale
30       *
31       * @return a String of length between min and max length according to the given locale
32       */
33      public String getWord(Integer length, Locale locale) {
34          SizeSortedWordList words = getWordList(locale);
35          //get the middle
36          int firstLength = (length.intValue() / 2);
37          //try to find a first word
38          String firstWord = null;
39          for (int i = firstLength; i < 50; i++) {
40              firstWord = words.getNextWord(new Integer(firstLength + i));
41              if (firstWord != null) {
42                  firstWord = firstWord.substring(0, firstLength);
43                  break;
44              }
45          }
46          String secondWord = null;
47          for (int i = firstLength; i < 50; i++) {
48              secondWord = words.getNextWord(new Integer(length.intValue()
49                      - firstLength + i));
50              if (secondWord != null) {
51                  secondWord =
52                          secondWord.substring(secondWord.length()
53                                  - length.intValue()
54                                  + firstLength,
55                                  secondWord.length());
56                  break;
57              }
58          }
59  
60          //if first word is still null, try with a smaller int avoiding
61          // infinite loop by chexking size
62  
63          firstWord = checkAndFindSmaller(firstWord, firstLength, locale);
64          secondWord = checkAndFindSmaller(secondWord, length.intValue()
65                  - firstLength, locale);
66          return firstWord + secondWord;
67  
68      }
69  
70      private String checkAndFindSmaller(String firstWord, int length,
71                                         Locale locale) {
72          //if first word is still null, try with a smaller int
73          // avoiding infinite loop by chexking size
74          if (firstWord == null) {
75              if (length > 1) {
76                  firstWord = getWord(new Integer(length), locale);
77              } else {
78                  throw new CaptchaException("No word of length : " +
79                          length + " exists in dictionnary! please " +
80                          "update your dictionary or your range!");
81              }
82          }
83          return firstWord;
84      }
85  
86  }