package jef.database.datasource; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.naming.InitialContext; import javax.naming.NameClassPair; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.sql.DataSource; import jef.common.log.LogUtil; import org.apache.commons.lang.StringUtils; /** * 通过JNDI查找Datasource * * 这个类也同时实现了DataSourceLookup和DataSourceInfoLookup接口 * @author jiyi * */ public class JndiDatasourceLookup implements DataSourceLookup,DataSourceInfoLookup{ private InitialContext ctx; private PasswordDecryptor passwordDecryptor; private String defaultKey; private String namePrifix=""; public DataSource getDataSource(String dataSourceName) { if(ctx==null){ init(); } try { DataSource ds = (DataSource) ctx.lookup(namePrifix+dataSourceName); DataSourceWrapper dw=DataSources.wrapFor(ds); if(dw==null){ return ds;//包装失败 }else{ return (DataSource) decrypt(dw);//包装成功,支持解密特性 } } catch (NamingException e) { LogUtil.exception("Can not lookup datasource from JNDI:" + dataSourceName, e); } return null; } public DataSourceInfo getDataSourceInfo(String dataSourceName) { if(ctx==null){ init(); } try { Object ds = ctx.lookup(namePrifix+dataSourceName); if(ds instanceof DataSourceInfo){ return decrypt((DataSourceInfo) ds); } DataSourceWrapper dw=DataSources.wrapFor((DataSource)ds); if(dw==null){ return null;//包装失败 }else{ return decrypt(dw);//包装成功,支持解密特性 } } catch (NamingException e) { LogUtil.exception("Can not lookup datasource from JNDI:" + dataSourceName, e); } return null; } private DataSourceInfo decrypt(DataSourceInfo dsi) { if(passwordDecryptor!=null){ String newpass=passwordDecryptor.decrypt(dsi.getPassword()); if(!StringUtils.equals(dsi.getPassword(), newpass)){ dsi.setPassword(newpass); } } return dsi; } private synchronized void init() { if(ctx!=null)return; try { ctx= new InitialContext(); } catch (NamingException e) { throw new IllegalStateException("JNDI init error.",e); } } public void setPasswordDecryptor(PasswordDecryptor passwordDecryptor) { passwordDecryptor=this.passwordDecryptor; } public void setDefaultKey(String defaultKey) { this.defaultKey = defaultKey; } public String getDefaultKey() { return defaultKey; } public Collection<String> getAvailableKeys() { if(ctx==null){ init(); } List<String> all=new ArrayList<String>(); try { NamingEnumeration<NameClassPair> o=ctx.list(""); for(;o.hasMore();){ NameClassPair e=o.next(); if(isDataSource(e.getClassName())){ all.add(e.getName()); } } } catch (NamingException e) { e.printStackTrace(); } return all; } private boolean isDataSource(String className) { Class<?> c; try { c=Class.forName(className); } catch (ClassNotFoundException e) { return false; } if(c==RoutingDataSource.class){ return false; } return DataSource.class.isAssignableFrom(c); } public String getNamePrifix() { return namePrifix; } public void setNamePrifix(String namePrifix) { if(namePrifix!=null) this.namePrifix = namePrifix; } }