new 抽象クラス名{}

インターセプタのバインド定義、com.google.inject.AbstractModule を実装時の
configureメソッドで記述したインターセプトが使用するリフレクション対象クラスを
指定させる先日のFtpInterceptor は気持ちわるい。
そこで、インターセプタを抽象クラスにして、インタセプトされるメソッドを記述
するクラスはこの抽象クラスを継承した上で、インタセプトMatcher に渡す3番目の
インスタンスは、new 抽象クラス名(){} で渡すトリッキーなことが必要である。

 binder().bindInterceptor(Matchers.any()
  ,FtpInterceptMatcher.annotatedWith(FtpMethod.class)
  ,new FtpInterceptor(対象の.class));
としていたのを
 binder().bindInterceptor(Matchers.any()
  ,FtpInterceptMatcher.annotatedWith(FtpMethod.class)
  ,new AbstractFtpInterceptor(){});
として、bindInterceptorの実行文を固定化する。

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

public abstract class AbstractFtpInterceptor implements MethodInterceptor{
   @FTPClientDefine private FTPClient _ftpclient;

   public FTPClient FTPClient(){
      return this._ftpclient;
   }


   @Override
   public Object invoke(MethodInvocation m) throws Throwable{
      // パラメータチェック
      String hostname = null;
      String user = null;
      String passwd = null;
      Object args = m.getArguments();
      Annotation
[] anos = m.getMethod().getParameterAnnotations();
      for(int n=0;n < anos.length;n++){
         for(int k=0;k < anos[n].length;k++){
            if (anos[n][k].annotationType().equals(FtpHost.class)){
               hostname = (String)args[n];
            }else if(anos[n][k].annotationType().equals(FtpUser.class)){
               user = (String)args[n];
            }else if(anos[n][k].annotationType().equals(FtpPasswd.class)){
               passwd = (String)args[n];
            }
         }
      }
      // FTPClientは、ここで生成して、ログイン後、実装に引き渡す!
      FTPClient ftpClient = new FTPClient();

      // コネクション
      ftpClient.connect(hostname);
      int reply = ftpClient.getReplyCode();
      if (!FTPReply.isPositiveCompletion(reply)) {
          throw new Exception("FTPClient  not Positive reply!! value = "+String.valueOf(reply));
      }
      // ログイン
      if (!ftpClient.login(user,passwd)){
         throw new Exception("FTPClient  Login NG!!  user = "+user);
      }
      // バイナリモード
      ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

      // 実装に引き渡す!
      Field ftpclientField = AbstractFtpInterceptor.class.getDeclaredField("_ftpclient");
      ftpclientField.setAccessible(true);


      ftpclientField.set(m.getThis(),ftpClient);

      // メソッド実行
      Object rtn = m.proceed();

      // ログアウト、切断
      if (ftpClient.isConnected()){
         //ftpClient.logout();
         ftpClient.disconnect();
      }
      return rtn;
   }
}

FTPClient() を呼び出すことで、インタセプトされるメソッド内で FTPClient を
取得できるようにしてある。