View Javadoc
1   /*
2    * Copyright (c) 2002-2014, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.captcha.modules.jcaptcha.service.sound;
35  
36  import java.security.SecureRandom;
37  import java.util.Locale;
38  import java.util.Random;
39  
40  import javax.sound.sampled.AudioInputStream;
41  
42  import com.octo.captcha.CaptchaException;
43  import com.octo.captcha.CaptchaQuestionHelper;
44  import com.octo.captcha.component.sound.wordtosound.WordToSound;
45  import com.octo.captcha.component.word.worddecorator.WordDecorator;
46  import com.octo.captcha.component.word.wordgenerator.WordGenerator;
47  import com.octo.captcha.sound.SoundCaptcha;
48  import com.octo.captcha.sound.SoundCaptchaFactory;
49  import com.octo.captcha.sound.gimpy.GimpySound;
50  
51  
52  /**
53   *
54   * @author lutecer
55   *
56   */
57  public class LuteceGimpySoundFactory extends SoundCaptchaFactory
58  {
59      /**
60       * The bundle question key for CaptchaQuestionHelper
61       */
62      public static final String MESSAGE_INVALID_EXCEPTION = "Invalid configuration for a ";
63      public static final String BUNDLE_QUESTION_KEY = GimpySound.class.getName(  );
64      private WordGenerator _wordGenerator;
65      private WordToSound _word2Sound;
66      private Random _myRandom = new SecureRandom(  );
67  
68      /**
69       * Construct a GimpySoundFactory from a word generator component and a wordtosound component
70       *
71       * @param thewordGenerator component
72       * @param theword2Sound    component
73       */
74      public LuteceGimpySoundFactory( WordGenerator thewordGenerator, WordToSound theword2Sound )
75      {
76          if ( thewordGenerator == null )
77          {
78              throw new CaptchaException( MESSAGE_INVALID_EXCEPTION + "GimpySoundFactory : WordGenerator can't be null" );
79          }
80  
81          if ( theword2Sound == null )
82          {
83              throw new CaptchaException( MESSAGE_INVALID_EXCEPTION + "GimpySoundFactory : Word2Sound can't be null" );
84          }
85  
86          _wordGenerator = thewordGenerator;
87          _word2Sound = theword2Sound;
88      }
89  
90      /**
91       * Construct a GimpySoundFactory from a word generator component and a wordtosound component
92       *
93       * @param wordGenerator the wordGenerator component
94       * @param word2Sound the word2Sound component
95       * @param wordDecorator the word Decodator
96       */
97      public LuteceGimpySoundFactory( WordGenerator wordGenerator, WordToSound word2Sound, WordDecorator wordDecorator )
98      {
99          if ( wordGenerator == null )
100         {
101             throw new CaptchaException( MESSAGE_INVALID_EXCEPTION +
102                 "SpellingSoundFactory : WordGenerator can't be null" );
103         }
104 
105         if ( word2Sound == null )
106         {
107             throw new CaptchaException( MESSAGE_INVALID_EXCEPTION + "SpellingSoundFactory : Word2Sound can't be null" );
108         }
109 
110         if ( wordDecorator == null )
111         {
112             throw new CaptchaException( MESSAGE_INVALID_EXCEPTION +
113                 "SpellingSoundFactory : wordAbstractor can't be null" );
114         }
115 
116         _wordGenerator = wordGenerator;
117         _word2Sound = word2Sound;
118     }
119 
120     /**
121      *
122      * @return the word to sound
123      */
124     public WordToSound getWordToSound(  )
125     {
126         return _word2Sound;
127     }
128 
129     /**
130      *
131      * @return the word generator
132      */
133     public WordGenerator getWordGenerator(  )
134     {
135         return _wordGenerator;
136     }
137 
138     /**
139      * @return a Sound Captcha
140      */
141     public SoundCaptcha getSoundCaptcha(  )
142     {
143         String word = _wordGenerator.getWord( getRandomLength(  ), Locale.getDefault(  ) ).toLowerCase(  );
144         AudioInputStream sound = _word2Sound.getSound( word );
145         SoundCaptcha soundCaptcha = new GimpySound( getQuestion( Locale.getDefault(  ) ), sound, word );
146 
147         return soundCaptcha;
148     }
149 
150     /**
151      * @param locale the locale
152      * @return a localized sound captcha
153      */
154     public SoundCaptcha getSoundCaptcha( Locale locale )
155     {
156         String word = _wordGenerator.getWord( getRandomLength(  ), locale ).toLowerCase(  );
157         AudioInputStream sound = _word2Sound.getSound( word, locale );
158         SoundCaptcha soundCaptcha = new GimpySound( getQuestion( locale ), sound, word );
159 
160         return soundCaptcha;
161     }
162 
163     /**
164      *
165      * @param locale the locale
166      * @return the question
167      */
168     protected String getQuestion( Locale locale )
169     {
170         return CaptchaQuestionHelper.getQuestion( locale, BUNDLE_QUESTION_KEY );
171     }
172 
173     /**
174      *
175      * @return the random length of word
176      */
177     protected Integer getRandomLength(  )
178     {
179         Integer wordLength;
180         int range = getWordToSound(  ).getMaxAcceptedWordLength(  ) - getWordToSound(  ).getMinAcceptedWordLength(  );
181         int randomRange = ( range != 0 ) ? _myRandom.nextInt( range + 1 ) : 0;
182         wordLength = Integer.valueOf( randomRange + getWordToSound( ).getMinAcceptedWordLength( ) );
183 
184         return wordLength;
185     }
186 }