こせきの技術日記

2006-07-07

[][] ドコモRFC違反アドレスを通すCommons EmailValidator拡張

メールアドレスのバリデーションで、ドコモRFC違反アドレスを許可する必要があったため、以下を作成しました。

Commons Validatorの1.3.0を使用しています。下のほうに、EmailValidatorが何を通すのかについて調べたテストケースも載せてあります。

Validatorの以前のバージョンでも動きそうな気がしますが、確認していません。

import org.apache.commons.validator.EmailValidator;
import org.apache.oro.text.perl.Perl5Util;

/**
 * ドコモ・auのRFC違反アドレスを通すように拡張したEmailValidatorです。
 * http://slashdot.jp/mobile/06/06/01/0931224.shtml
 */
public class EmailDocomoValidator extends EmailValidator {
    
    // 以下は変更なし。コピーしただけ。
    private static final String SPECIAL_CHARS = "\\(\\)<>@,;:'\\\\\\\"\\.\\[\\]";
    private static final String VALID_CHARS = "[^\\s" + SPECIAL_CHARS + "]";    
    private static final String QUOTED_USER = "(\"[^\"]*\")";
    private static final String WORD = "((" + VALID_CHARS + "|')+|" + QUOTED_USER + ")";
    
    // ユーザ名の中の連続したピリオドと末尾の連続したピリオドを許可。
    private static final String USER_PATTERN = "/^\\s*" + WORD + "(\\.+" + WORD + ")*\\.*$/";

    /**
     * Singleton instance of this class.
     */
    private static final EmailDocomoValidator DOCOMO_VALIDATOR = new EmailDocomoValidator();

    /**
     * Returns the Singleton instance of this validator.
     * @return singleton instance of this validator.
     */
    public static EmailDocomoValidator getInstance() {
        return DOCOMO_VALIDATOR;
    }
    
    protected boolean isValidUser(String user) {
        Perl5Util userMatcher = new Perl5Util();
        return userMatcher.match(USER_PATTERN, user);
    }
}

テストケース。

import junit.framework.TestCase;

import org.apache.commons.validator.EmailValidator;


/**
 * 
 * @author koseki
 */
public class EmailDocomoValidatorTest extends TestCase {
    private static final EmailValidator validator = EmailValidator.getInstance();
    private static final EmailDocomoValidator docomo = EmailDocomoValidator.getInstance();

    public void testValidation() {

        // O ... OK
        // X ... NG
        String[] addresses = new String[] {
                "OO","test@example.com",
                
                // ドコモのRFC違反アドレスはEmailValidatorでは通らない。
                // EmailDocomoValidatorは通す。
                "XO","teribble.@docomo.ne.jp",
                "XO","so..terrible@docomo.ne.jp",
                
                // ドットは先頭に書けない。ドコモも先頭のドットは許可していない風。
                "XX",".terrible@example.com", 

                // ユーザ名にシングルクォートを使用できる。
                "OO","test's@example.com", 
                "OO","test'''''@example.com", 
                "OO","'@example.com", 
                
                // ダブルクォートの中には@も含め何でも書ける。
                "OO","\"test\"@example.com", // OK
                "OO","\"@\"@example.com", // OK
                "OO","\"test @@@@@@@@@@@@@@@@@ abababa\".a'a'a.\"test\"@example.com", // OK
                "OO","\"good.\"@docomo.ne.jp",  // OK
                "OO","\"goo...oood\"@docomo.ne.jp",  // OK
                "OO","\".good\"@example.com",  // OK
                
                // ダブルクォートの前後はドットなら書ける。
                "OO","\"test\".aaa.\"test\"@example.com", // OK
                "XX","\"test\"aaa@example.com", // NG
                "XX","aaa\"test\"@example.com", // NG
                
                // localhostはダメ
                "XX","hikky@localhost", // NG
                
                // []で囲ってIP指定できる。
                "OO","a.b.c@[192.168.0.1]", // OK
                "XX","a.b.c@192.168.0.1", // NG
                
                // TLDは2文字以上。数字は不可。TLD_PATTERN参照。
                "XX","test@example.", // NG
                "XX","test@example.1", // NG
                "XX","test@example.a", // NG
                "OO","test@example.ab", // OK
                "XX","test@example.12", // NG
                "OO","test@12.com", // OK
                "XX","test@12.12", // NG
                "XX","test@1.a", // NG
                "OO","test@1.ab", // OK
                "OO","test@1.AB", // OK
        };

        for (int i = 0; i < addresses.length; i+=2) {
            validate(addresses[i], addresses[i+1]);
        }
    }
    
    private void validate(String expected, String email) {
        String result = validator.isValid(email) ? "O" : "X";
        result += docomo.isValid(email) ? "O" : "X";
        assertEquals("address:" + email, expected, result);
    }
}

[][] -Declipse.downloadSourcesをpom.xmlで指定

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-eclipse-plugin</artifactId>
  <version>2.0</version>
  <configuration>
    <downloadSources>true</downloadSources>
  </configuration>
</plugin>

試してないけど。

[][][] Maven2がEclipseの手動でアタッチしたソースを外してくれる

  1. eclipse.downloadSourcesをtrueに設定。
  2. mvn eclipse:eclipseを実行する。
  3. リポジトリからソースが見つけられない場合に、
  4. 手動でアタッチしたソースが消されてしまう。

せっかく設定したのに全部消えた。もーー。

eclipse.downloadSourcesは素晴らしい機能なのでオフにしたくないんだけどなー。困った。

[][][] Maven2でJunit4を使う方法

あとで調べる。

[][] KijimunaのdiconエディタのキーバインディングEmacsにする方法は?

Emacs設定にできないのかなー。

インクリメンタル検索に失敗する操作ミスを何度も繰り返していい加減フラストレーションがたまるので、diconエディタを使うのを一旦やめた。