001 /******************************************************************************* 002 * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian 003 * Thomschke. 004 * 005 * All Rights Reserved. This program and the accompanying materials 006 * are made available under the terms of the Eclipse Public License v1.0 007 * which accompanies this distribution, and is available at 008 * http://www.eclipse.org/legal/epl-v10.html 009 * 010 * Contributors: 011 * Sebastian Thomschke - initial implementation. 012 *******************************************************************************/ 013 package net.sf.oval.constraint; 014 015 import java.util.regex.Pattern; 016 017 import net.sf.oval.ConstraintTarget; 018 import net.sf.oval.Validator; 019 import net.sf.oval.configuration.annotation.AbstractAnnotationCheck; 020 import net.sf.oval.context.OValContext; 021 import net.sf.oval.exception.OValException; 022 023 /** 024 * @author Sebastian Thomschke 025 */ 026 public class EmailCheck extends AbstractAnnotationCheck<Email> 027 { 028 private static final long serialVersionUID = 1L; 029 030 private static final String SPECIAL_CHARACTERS = "'\\(\\)\\-\\.`"; 031 private static final String ASCII = "\\w " + SPECIAL_CHARACTERS; 032 private static final String ASCII_WITHOUT_COMMA = "[" + ASCII + "]+"; 033 private static final String ASCII_WITH_COMMA = "\"[" + ASCII + ",]+\""; 034 private static final String ASCII_WITH_QUESTION_MARK_AND_EQUALS = "[" + ASCII + "\\?\\=]+"; 035 private static final String MIME_ENCODED = "\\=\\?" + ASCII_WITH_QUESTION_MARK_AND_EQUALS + "\\?\\="; 036 private static final String NAME = "(" + ASCII_WITHOUT_COMMA + "|" + ASCII_WITH_COMMA + "|" + MIME_ENCODED + ")"; 037 038 private static final String EMAIL_BASE_PATTERN = "['_A-Za-z0-9-&]+(\\.['_A-Za-z0-9-&]+)*[.]{0,1}@([A-Za-z0-9-])+(\\.[A-Za-z0-9-]+)*((\\.[A-Za-z0-9]{2,})|(\\.[A-Za-z0-9]{2,}\\.[A-Za-z0-9]{2,}))"; 039 040 private static final Pattern EMAIL_PATTERN = Pattern.compile("^" + EMAIL_BASE_PATTERN + "$"); 041 042 private static final Pattern EMAIL_WITH_PERSONAL_NAME_PATTERN = Pattern.compile("^(" + EMAIL_BASE_PATTERN + "|" 043 + NAME + " +<" + EMAIL_BASE_PATTERN + ">)$"); 044 045 private boolean allowPersonalName; 046 047 /** 048 * {@inheritDoc} 049 */ 050 @Override 051 public void configure(final Email constraintAnnotation) 052 { 053 super.configure(constraintAnnotation); 054 setAllowPersonalName(constraintAnnotation.allowPersonalName()); 055 } 056 057 /** 058 * {@inheritDoc} 059 */ 060 @Override 061 protected ConstraintTarget[] getAppliesToDefault() 062 { 063 return new ConstraintTarget[]{ConstraintTarget.VALUES}; 064 } 065 066 /** 067 * @return the allowPersonalName 068 */ 069 public boolean isAllowPersonalName() 070 { 071 return allowPersonalName; 072 } 073 074 /** 075 * {@inheritDoc} 076 */ 077 public boolean isSatisfied(final Object validatedObject, final Object valueToValidate, final OValContext context, 078 final Validator validator) throws OValException 079 { 080 if (valueToValidate == null) return true; 081 082 if (allowPersonalName) return EMAIL_WITH_PERSONAL_NAME_PATTERN.matcher(valueToValidate.toString()).matches(); 083 return EMAIL_PATTERN.matcher(valueToValidate.toString()).matches(); 084 } 085 086 /** 087 * @param allowPersonalName the allowPersonalName to set 088 */ 089 public void setAllowPersonalName(final boolean allowPersonalName) 090 { 091 this.allowPersonalName = allowPersonalName; 092 } 093 }