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);
}
}
}
}
}