Velocity & Google guice(2)

Google guice で org.apache.velocity.Template 生成プロバイダと、VelocityEngine で初期化する
属性値のインジェクトポイントを作成できたら、次はいよいよ、
com.google.inject.AbstractModule で、Template のバインド定義と
bindListener によるバインド定義。
このクラスを継承したときに、再度、
bindListener(Matchers.any(),new _VelocityPropertyLitsener());
を実行できるように、インナークラスを public にしている。

import java.lang.reflect.Field;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
import jp.jsuite.util.ApplicationProperties;
import org.apache.velocity.Template;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.apache.velocity.runtime.resource.loader.FileResourceLoader;
import com.google.inject.AbstractModule;
import com.google.inject.MembersInjector;
import com.google.inject.TypeLiteral;
import com.google.inject.matcher.Matchers;
import com.google.inject.spi.TypeEncounter;
import com.google.inject.spi.TypeListener;
/**
 * VelocityProvider → Template生成
 * & VelocityEngine init の Properties 生成バインド定義
 */

public class VelocityTemplateModule extends AbstractModule{
   protected String vmname;
   String resourceKey;

   public VelocityTemplateModule(){
      this.vmname = null;
      this.resourceKey = null;
   }
   public VelocityTemplateModule(String vmname){
      this.vmname = vmname;
      this.resourceKey = null;
   }
   public VelocityTemplateModule(String vmname,String resourceKey){
      this.vmname = vmname;
      this.resourceKey = resourceKey;
   }
   /*
    * @see com.google.inject.AbstractModule#configure()
    */

   @Override
   protected void configure(){
      if (this.vmname != null){
         binder().bind(Template.class).toProvider(new VelocityProvider(this.vmname));
      }
      bindListener(Matchers.any(),new _VelocityPropertyLitsener());
   }
   public class _VelocityPropertyLitsener implements TypeListener{

      /*
       * @see com.google.inject.spi.TypeListener#hear(com.google.inject.TypeLiteral
       *                                            , com.google.inject.spi.TypeEncounter)
       */

      @Override
      public <T> void hear(TypeLiteral<T> typeLiteral,TypeEncounter<T> typeEncounter){
         for(Field field : typeLiteral.getRawType().getDeclaredFields()){
            if (field.getType()==Properties.class && field.isAnnotationPresent(VelocityProperty.class)){
               // Properties変数で、@VelocityProperty が付いてるもの
               typeEncounter.register(new _PropertyInjector<T>(field));
            }
         }
      }
      class _PropertyInjector<T> implements MembersInjector<T>{
         private final Field field;
         _PropertyInjector(Field field){
            this.field = field;
            this.field.setAccessible(true);
         }

         /*
          * @see com.google.inject.MembersInjector#injectMembers(java.lang.Object)
          */

         @Override
         public void injectMembers(T t){
            try{
            Properties p = new Properties();
            p.setProperty("resource.loader","file,class");
            p.setProperty("file.resource.loader.class",FileResourceLoader.class.getName());
            p.setProperty("class.resource.loader.class",ClasspathResourceLoader.class.getName());
            p.setProperty("runtime.log.logsystem.class","org.apache.velocity.runtime.log.NullLogSystem");
            if (VelocityTemplateModule.this.resourceKey==null){
               ApplicationProperties ap = ApplicationProperties.getInstance();
               if (ap.getProperty("file.resource.loader.path") != null){
                  p.setProperty("file.resource.loader.path",ap.getProperty("file.resource.loader.path"));
               }
               if (ap.getProperty("input.encoding") != null){
                  p.setProperty("input.encoding",ap.getProperty("input.encoding"));
               }
               if (ap.getProperty("output.encoding") != null){
                  p.setProperty("output.encoding",ap.getProperty("output.encoding"));
               }
            }else{
               try{
               ResourceBundle rs = ResourceBundle.getBundle(VelocityTemplateModule.this.resourceKey);
               p.setProperty("file.resource.loader.path",rs.getString("file.resource.loader.path"));
               p.setProperty("input.encoding",rs.getString("input.encoding"));
               p.setProperty("output.encoding",rs.getString("output.encoding"));
               this.field.set(t,p);
               }catch(MissingResourceException e){
               }
            }
            this.field.set(t,p);
            }catch(IllegalAccessException e){
               throw new RuntimeException(e);
            }
         }
      }
   }

}