001: /*
002: * $Header: /cvsroot/mvnforum/mvnforum/src/com/mvnforum/common/MVNCaptchaService.java,v 1.14 2007/10/09 11:09:16 lexuanttkhtn Exp $
003: * $Author: lexuanttkhtn $
004: * $Revision: 1.14 $
005: * $Date: 2007/10/09 11:09:16 $
006: *
007: * ====================================================================
008: *
009: * Copyright (C) 2002-2007 by MyVietnam.net
010: *
011: * All copyright notices regarding mvnForum MUST remain
012: * intact in the scripts and in the outputted HTML.
013: * The "powered by" text/logo with a link back to
014: * http://www.mvnForum.com and http://www.MyVietnam.net in
015: * the footer of the pages MUST remain visible when the pages
016: * are viewed on the internet or intranet.
017: *
018: * This program is free software; you can redistribute it and/or modify
019: * it under the terms of the GNU General Public License as published by
020: * the Free Software Foundation; either version 2 of the License, or
021: * any later version.
022: *
023: * This program is distributed in the hope that it will be useful,
024: * but WITHOUT ANY WARRANTY; without even the implied warranty of
025: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
026: * GNU General Public License for more details.
027: *
028: * You should have received a copy of the GNU General Public License
029: * along with this program; if not, write to the Free Software
030: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
031: *
032: * Support can be obtained from support forums at:
033: * http://www.mvnForum.com/mvnforum/index
034: *
035: * Correspondence and Marketing Questions can be sent to:
036: * info at MyVietnam net
037: *
038: * @author: Minh Nguyen
039: * @author: Mai Nguyen
040: */
041: package com.mvnforum.common;
042:
043: import java.awt.Color;
044: import java.awt.image.BufferedImage;
045: import java.io.IOException;
046: import java.io.OutputStream;
047: import java.util.ArrayList;
048: import java.util.Iterator;
049:
050: import javax.imageio.ImageIO;
051: import javax.servlet.http.HttpServletRequest;
052: import javax.servlet.http.HttpServletResponse;
053:
054: import net.myvietnam.mvncore.exception.DatabaseException;
055:
056: import com.mvnforum.auth.AuthenticationException;
057: import com.mvnforum.auth.OnlineUserManager;
058: import com.octo.captcha.component.image.backgroundgenerator.*;
059: import com.octo.captcha.component.image.fontgenerator.FontGenerator;
060: import com.octo.captcha.component.image.fontgenerator.TwistedAndShearedRandomFontGenerator;
061: import com.octo.captcha.component.image.textpaster.*;
062: import com.octo.captcha.component.image.wordtoimage.ComposedWordToImage;
063: import com.octo.captcha.component.image.wordtoimage.WordToImage;
064: import com.octo.captcha.component.wordgenerator.RandomWordGenerator;
065: import com.octo.captcha.component.wordgenerator.WordGenerator;
066: import com.octo.captcha.engine.image.ListImageCaptchaEngine;
067: import com.octo.captcha.image.ImageCaptchaFactory;
068: import com.octo.captcha.image.gimpy.GimpyFactory;
069:
070: public class MVNCaptchaService extends ListImageCaptchaEngine {
071:
072: private static final Integer MIN_WORD_LENGTH = new Integer(6);
073:
074: private static final Integer MAX_WORD_LENGTH = new Integer(8);
075:
076: private static final Integer IMAGE_WIDTH = new Integer(380);
077:
078: private static final Integer IMAGE_HEIGHT = new Integer(80);
079:
080: private static final Integer MIN_FONT_SIZE = new Integer(44);
081:
082: private static final Integer MAX_FONT_SIZE = new Integer(50);
083:
084: private static final String NUMERIC_CHARS = "123456789";// No numeric 0
085:
086: private static final String UPPER_ASCII_CHARS = "ABCDEFGHJKLMNPQRSTUVWXYZ";// No upper O I
087:
088: // we dont use the lower characters because it cause dificult in some case, so that
089: // we must always UPPERCASE the input from user (currently in OnlineUserImpl)
090: //private static final String LOWER_ASCII_CHARS= "abcdefghjklmnpqrstuvwxyz";// No lower o i
091:
092: /**
093: * Singleton instance of this class
094: */
095: private static MVNCaptchaService instance = new MVNCaptchaService();
096:
097: private ArrayList textPasterList;
098:
099: private ArrayList backgroundGeneratorList;
100:
101: private ArrayList fontGeneratorList;
102:
103: /**
104: * Private constructor to prevent instantiation
105: */
106: private MVNCaptchaService() {
107: }
108:
109: public static MVNCaptchaService getInstance() {
110: return instance;
111: }
112:
113: protected void buildInitialFactories() {
114: textPasterList = new ArrayList();
115: backgroundGeneratorList = new ArrayList();
116: fontGeneratorList = new ArrayList();
117:
118: textPasterList.add(new SimpleTextPaster(MIN_WORD_LENGTH,
119: MAX_WORD_LENGTH, Color.green));
120: textPasterList.add(new RandomTextPaster(MIN_WORD_LENGTH,
121: MAX_WORD_LENGTH, Color.green));
122: textPasterList.add(new SimpleTextPaster(MIN_WORD_LENGTH,
123: MAX_WORD_LENGTH, Color.red));
124: textPasterList.add(new RandomTextPaster(MIN_WORD_LENGTH,
125: MAX_WORD_LENGTH, Color.red));
126: textPasterList.add(new SimpleTextPaster(MIN_WORD_LENGTH,
127: MAX_WORD_LENGTH, Color.blue));
128: textPasterList.add(new RandomTextPaster(MIN_WORD_LENGTH,
129: MAX_WORD_LENGTH, Color.blue));
130:
131: backgroundGeneratorList.add(new EllipseBackgroundGenerator(
132: IMAGE_WIDTH, IMAGE_HEIGHT));
133: backgroundGeneratorList.add(new UniColorBackgroundGenerator(
134: IMAGE_WIDTH, IMAGE_HEIGHT));
135: backgroundGeneratorList
136: .add(new MultipleShapeBackgroundGenerator(IMAGE_WIDTH,
137: IMAGE_HEIGHT));
138: backgroundGeneratorList.add(new FunkyBackgroundGenerator(
139: IMAGE_WIDTH, IMAGE_HEIGHT));
140: backgroundGeneratorList.add(new GradientBackgroundGenerator(
141: IMAGE_WIDTH, IMAGE_HEIGHT, Color.white, Color.black));
142: backgroundGeneratorList.add(new GradientBackgroundGenerator(
143: IMAGE_WIDTH, IMAGE_HEIGHT, Color.black, Color.white));
144: backgroundGeneratorList
145: .add(new GradientBackgroundGenerator(IMAGE_WIDTH,
146: IMAGE_HEIGHT, Color.orange, Color.magenta));
147: /*
148: try {
149: // minhnn: In Resin, it loads as 'C:\soft\resin-3.0.8\file:\C:\soft\resin-3.0.8\webapps\mvnforum\WEB-INF\lib\jcaptcha-engine-1.0-RC1.jar!\gimpybackgrounds'
150: // so it cannot load this directory, I guess this is Resin bugs
151: //backgroundGeneratorList.add(new FileReaderRandomBackgroundGenerator(IMAGE_WIDTH, IMAGE_HEIGHT, "/gimpybackgrounds/"));
152: } catch (CaptchaException ex) {
153: // should use common-logging
154: // Cannot call this because of NPE (dont know why): ex.printStackTrace();
155: }*/
156:
157: fontGeneratorList.add(new TwistedAndShearedRandomFontGenerator(
158: MIN_FONT_SIZE, MAX_FONT_SIZE));
159: //fontGeneratorList.add(new TwistedRandomFontGenerator(MIN_FONT_SIZE, MAX_FONT_SIZE));// link character too much
160: //fontGeneratorList.add(new RandomFontGenerator(MIN_FONT_SIZE, MAX_FONT_SIZE));// to easy to read
161: //fontGeneratorList.add(new DeformedRandomFontGenerator(MIN_FONT_SIZE, MAX_FONT_SIZE));// to small font
162:
163: // no char upper O, char lower o and numerric 0 because user cannot answer
164: WordGenerator words = new RandomWordGenerator(NUMERIC_CHARS
165: + UPPER_ASCII_CHARS);
166:
167: for (Iterator fontIter = fontGeneratorList.iterator(); fontIter
168: .hasNext();) {
169: FontGenerator font = (FontGenerator) fontIter.next();
170: for (Iterator backIter = backgroundGeneratorList.iterator(); backIter
171: .hasNext();) {
172: BackgroundGenerator back = (BackgroundGenerator) backIter
173: .next();
174: for (Iterator textIter = textPasterList.iterator(); textIter
175: .hasNext();) {
176: TextPaster parser = (TextPaster) textIter.next();
177:
178: WordToImage word2image = new ComposedWordToImage(
179: font, back, parser);
180: ImageCaptchaFactory factory = new GimpyFactory(
181: words, word2image);
182: addFactory(factory);
183: }
184: }
185: }
186: }
187:
188: /**
189: * Write the captcha image of current user to the servlet response
190: *
191: * @param request HttpServletRequest
192: * @param response HttpServletResponse
193: * @throws IOException
194: */
195: public void writeCaptchaImage(HttpServletRequest request,
196: HttpServletResponse response) throws IOException,
197: DatabaseException, AuthenticationException {
198:
199: BufferedImage image = OnlineUserManager.getInstance()
200: .getOnlineUser(request).getCurrentCaptchaImage();
201: if (image == null) {
202: return;
203: }
204:
205: OutputStream outputStream = null;
206: try {
207: response.setHeader("Cache-Control", "no-store, no-cache"); // HTTP 1.1
208: //response.setHeader("Cache-Control", "no-cache"); // HTTP 1.1
209: response.setHeader("Pragma", "no-cache"); // HTTP 1.0
210: response.setDateHeader("Expires", 0);
211: response.setContentType("image/jpeg");
212:
213: outputStream = response.getOutputStream();
214:
215: // JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outputStream);
216: //encoder.encode(image);
217: ImageIO.write(image, "jpeg", outputStream);
218:
219: outputStream.flush();
220: outputStream.close();
221: outputStream = null;// no close twice
222: } catch (IOException ex) {
223: throw ex;
224: } finally {
225: if (outputStream != null) {
226: try {
227: outputStream.close();
228: } catch (IOException ex) {
229: }
230: }
231: }
232: }
233:
234: /*
235: public void writeTestCaptchaImage(HttpServletRequest request, HttpServletResponse response)
236: throws IOException {
237:
238: ImageCaptcha imageCaptcha = getNextImageCaptcha();
239: BufferedImage image = (BufferedImage)imageCaptcha.getChallenge();
240:
241: OutputStream outputStream = null;
242: try {
243: outputStream = response.getOutputStream();
244: response.setContentType("image/jpeg");
245:
246: JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outputStream);
247: encoder.encode(image);
248:
249: outputStream.flush();
250: outputStream.close();
251: outputStream = null;// no close twice
252: } catch (IOException ex) {
253: throw ex;
254: } finally {
255: if (outputStream != null) {
256: try {
257: outputStream.close();
258: } catch (IOException ex) { }
259: }
260: imageCaptcha.disposeChallenge();
261: }
262: }
263:
264: private void testCaptchaImage(String folder) {
265: if (folder == null) {
266: folder = "c:\\";
267: }
268: if (folder.endsWith("\\") == false) {
269: folder = folder + "\\";
270: }
271:
272: WordGenerator words = new RandomWordGenerator("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
273:
274: for (Iterator fontIter = fontGeneratorList.iterator(); fontIter.hasNext(); ) {
275: FontGenerator font = (FontGenerator)fontIter.next();
276: for (Iterator backIter = backgroundGeneratorList.iterator(); backIter.hasNext(); ) {
277: BackgroundGenerator back = (BackgroundGenerator)backIter.next();
278: for (Iterator textIter = textPasterList.iterator(); textIter.hasNext(); ) {
279: TextPaster parser = (TextPaster)textIter.next();
280:
281: WordToImage word2image = new ComposedWordToImage(font, back, parser);
282: ImageCaptchaFactory factory = new GimpyFactory(words, word2image);
283:
284: ImageCaptcha imageCaptcha = factory.getImageCaptcha();
285: String filename = "TestCaptcha_" + getClassName(font) + "_" + getClassName(back) + "_" + getClassName(parser) + ".jpg";
286: try {
287: ImageUtil.writeJpegImage_Sun((BufferedImage) imageCaptcha.getChallenge(), folder + filename);
288: } catch (IOException ex) {
289: ex.printStackTrace();
290: return;
291: }
292: }
293: }
294: }
295: }
296:
297: private String getClassName(Object obj) {
298: String fullName = obj.getClass().getName();
299: int dotIndex = fullName.lastIndexOf('.');
300: if (dotIndex == -1) {
301: return fullName;
302: }
303: return fullName.substring(dotIndex + 1);
304: }
305:
306: public static void main(String[] args) throws IOException {
307: MVNCaptchaService.getInstance().testCaptchaImage("c:\\temp\\testcaptcha");
308: }
309: */
310: }
|