/* * Copyright (C) 2010---2014 星星(wuweixing)<349446658@qq.com> * * This file is part of Wabacus * * Wabacus is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.wabacus.config.database.datasource; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.List; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; import org.logicalcobwebs.proxool.ProxoolFacade; import org.logicalcobwebs.proxool.configuration.JAXPConfigurator; import com.wabacus.config.Config; import com.wabacus.config.ConfigLoadManager; import com.wabacus.config.xml.XmlAssistant; import com.wabacus.exception.WabacusConfigLoadingException; import com.wabacus.exception.WabacusRuntimeException; import com.wabacus.system.assistant.WabacusAssistant; import com.wabacus.util.DesEncryptTools; import com.wabacus.util.Tools; public class ProxoolDataSource extends AbsDataSource { private static Log log=LogFactory.getLog(ProxoolDataSource.class); private String alias; private boolean isClosedPool=false; public String getAlias() { return alias; } public void setAlias(String alias) { this.alias=alias; } public Connection getConnection() { try { log.debug("从数据源"+this.getName()+"获取数据库连接"); return DriverManager.getConnection(alias); }catch(SQLException e) { throw new WabacusRuntimeException("获取数据库连接失败",e); } } public DataSource getDataSource() { throw new WabacusRuntimeException("不能从ProxoolDataSource数据源类型中获取javax.sql.DataSource对象"); } public void closePool() { super.closePool(); if(!isClosedPool) { log.debug("正在关闭Proxool连接池......................................"); ProxoolFacade.shutdown(0); isClosedPool=true; alias=null; } } public void loadConfig(Element eleDataSource) { super.loadConfig(eleDataSource); List lstEleProperties=eleDataSource.elements("property"); if(lstEleProperties==null||lstEleProperties.size()==0) { throw new WabacusConfigLoadingException("没有为数据源:"+this.getName()+"配置alias、configfile等参数"); } String configfile=null; Element eleChild; String name; String value; for(int i=0;i<lstEleProperties.size();i++) { eleChild=(Element)lstEleProperties.get(i); name=eleChild.attributeValue("name"); value=eleChild.getText(); name=name==null?"":name.trim(); value=value==null?"":value.trim(); if(name.equals("alias")) { alias=value; }else if(name.equals("configfile")) { configfile=value; } } if(alias==null||alias.trim().equals("")) { throw new WabacusConfigLoadingException("没有为数据源"+this.getName()+"配置alias"); } alias="proxool."+alias.trim(); if(configfile==null||configfile.trim().equals("")) { throw new WabacusConfigLoadingException("没有为数据源"+this.getName()+"配置configfile"); } changePassword(configfile,false); BufferedInputStream bis=null; try { if(Tools.isDefineKey("classpath",Config.configpath)) { if(configfile.startsWith("/")) { configfile=configfile.substring(1); } bis=new BufferedInputStream(ConfigLoadManager.currentDynClassLoader.getResourceAsStream(WabacusAssistant.getInstance() .getRealFilePath(Config.configpath,configfile))); }else { bis=new BufferedInputStream(new FileInputStream( new File(WabacusAssistant.getInstance().getRealFilePath(Config.configpath,configfile)))); } if(!configfile.toLowerCase().endsWith(".xml")) { throw new WabacusConfigLoadingException("加载配置文件"+configfile+"失败,不合法的文件格式,wabacus只支持使用.xml配置proxool数据源"); } JAXPConfigurator.configure(new InputStreamReader(bis),false); }catch(Exception e) { throw new WabacusConfigLoadingException("加载配置文件"+configfile+"失败",e); }finally { if(bis!=null) { try { bis.close(); }catch(IOException e) { e.printStackTrace(); } bis=null; } } changePassword(configfile,true); } private void changePassword(String configfile,boolean actiontype) { if(!configfile.toLowerCase().endsWith(".xml")) { throw new WabacusConfigLoadingException("加载配置文件"+configfile+"失败,不合法的文件格式,wabacus只支持使用.xml配置proxool数据源"); } Document doc=XmlAssistant.getInstance().loadXmlDocument(configfile); Element root=doc.getRootElement(); Element eleDriverProp=root.element("driver-properties"); if(eleDriverProp==null) return; List lstProps=eleDriverProp.elements("property"); if(lstProps==null||lstProps.size()==0) { return; } Element elePasswordProp=null; for(int i=0;i<lstProps.size();i++) { if("password".equalsIgnoreCase(((Element)lstProps.get(i)).attributeValue("name").trim())) { elePasswordProp=(Element)lstProps.get(i); } } if(elePasswordProp==null) return; String password=elePasswordProp.attributeValue("value"); password=password==null?"":password.trim(); if(password.equals("")) return; boolean shouldsave=false; if(actiontype) { if(DesEncryptTools.KEY_OBJ==null) return;//没有在wabacus.cfg.xml中指定密钥,则不加密 if(password.startsWith("{3DES}")) { if(DesEncryptTools.IS_NEWKEY) { throw new WabacusConfigLoadingException("密钥文件已经改变,但"+configfile+"中已有用旧密钥加密好的密码,它们将无法解密,请将它们先置成明文再换密钥文件"); } }else if(!password.equals("")) { password="{3DES}"+DesEncryptTools.encrypt(password); shouldsave=true; } }else { if(password.startsWith("{3DES}")) { if(DesEncryptTools.IS_NEWKEY) { throw new WabacusConfigLoadingException("密钥文件已经改变,但"+configfile+"中已有用旧密钥加密好的密码,它们将无法解密,请将它们先置成明文再换密钥文件"); } if(DesEncryptTools.KEY_OBJ==null) { throw new WabacusConfigLoadingException("没有在wabacus.cfg.xml中指定密钥文件,"+configfile+"中已加密的密码无法解密"); } password=DesEncryptTools.decrypt(password.substring("{3DES}".length())); shouldsave=true; } } if(shouldsave) { Attribute attrPass=elePasswordProp.attribute("value"); attrPass.setValue(password); try { XmlAssistant.getInstance().saveDocumentToXmlFile(configfile,doc); }catch(IOException e) { log.warn(configfile+"中的数据源密码加密失败,将存放明文的密码",e); } } } protected void finalize() throws Throwable { closePool(); super.finalize(); } }