001package gu.sql2java; 002 003import static gu.sql2java.SimpleLog.*; 004 005import java.io.File; 006import java.io.FileWriter; 007import java.io.IOException; 008import java.io.InputStream; 009import java.io.InputStreamReader; 010import java.net.URL; 011import java.util.HashSet; 012import java.util.Properties; 013import java.util.Set; 014/** 015 * 配置文件读取工具类 016 * @author guyadong 017 * 018 */ 019public class ConfigUtils { 020 private static final String JAR_SUFFIX = ".jar"; 021 022 /** 023 * 顺序加载不同位置的properties文件,加载顺序为:<br> 024 * 1.调用{@link ClassLoader#getResource(String)}方法在{@code clazz}所在位置查找,如果失败则抛出异常<br> 025 * 2.如果class在jar包中,则尝试读取在jar所在位置../confFolder/propFile,tomcat下即为WEB-INF/confFolder/propFile<br> 026 * 3.如果环境变量envVar定义,则从envVar指定的目录下读取propFile<br> 027 * 4.user.dir下查找confFolder/propFile加载配置<br> 028 * 后面的配置变量会覆盖前面的定义<br> 029 * @param propFile 要加载的properties文件名,为{@code null}或空时抛出异常 {@link IllegalArgumentException} 030 * @param confFolder popFile所在文件夹,{@code null}时使用默认值'conf' 031 * @param envVar 环境变量名 用于定义propFile位置,可为{@code null} 032 * @param clazz 用于获取 {@link ClassLoader}的类,为null时使用本类的class 033 * @param showProp 加载后是否显示所有值 034 * @return 返回加载后的{@link Properties}对象 035 */ 036 public static Properties loadAllProperties(String propFile, String confFolder, String envVar, Class<?> clazz, boolean showProp) { 037 if(null==propFile||propFile.isEmpty()){ 038 throw new IllegalArgumentException("the argument 'propFile' must not be null or empty"); 039 } 040 if (null == confFolder){ 041 confFolder = "conf"; 042 } 043 if (null == clazz){ 044 clazz = ConfigUtils.class; 045 } 046 final String fileSeparator = System.getProperty("file.separator"); 047 String propPath = confFolder.concat(System.getProperty("file.separator")).concat(propFile); 048 Properties props = new Properties(); 049 Set<File> loadedFiles = new HashSet<File>(); 050 try { 051 // 在jar包中查找默认配置文件 052 URL url = clazz.getClassLoader().getResource(propPath.replace(fileSeparator, "/")); 053 if(null==url){ 054 throw new ExceptionInInitializerError(String.format("not found default properties %s", propPath)); 055 } 056 loadProperties(url, props); 057 } catch (Exception e) { 058 // 默认配置必须加载成功否则抛出异常 059 throw new ExceptionInInitializerError(String.format("fail to load default properties(加载默认配置文件失败) %s cause by %s", propPath, 060 e.getMessage())); 061 } 062 try { 063 // 加载 jar包所在位置 ../conf/cassdk.properties 064 URL classLocation = clazz.getProtectionDomain().getCodeSource().getLocation(); 065 if (classLocation.toString().endsWith(JAR_SUFFIX)) { 066 // jar包所在目录的父目录,tomcat下即为WEB-INF 067 File jarParent = new File(classLocation.getPath()).getParentFile().getParentFile(); 068 if (null != jarParent) { 069 File confFile = new File(jarParent, propPath); 070 if (confFile.isFile()) { 071 loadProperties(confFile.toURI().toURL(), props); 072 loadedFiles.add(confFile); 073 } 074 } 075 } 076 } catch (Exception e) { 077 } 078 try { 079 // 通过环境变量查找properties文件 080 if (envVar != null && !envVar.isEmpty()) { 081 String cf = System.getProperty(envVar); 082 if (null != cf&&!cf.isEmpty()) { 083 File envFile = new File(cf, propFile); 084 if (!loadedFiles.contains(envFile)) { 085 loadProperties(envFile.toURI().toURL(), props); 086 loadedFiles.add(envFile); 087 } 088 } else { 089 log("not defined environment variable '%s'", envVar); 090 } 091 } 092 } catch (Exception e) { 093 } 094 try { 095 // 在当前路径下查找配置文件 096 File propInUserDir = new File(System.getProperty("user.dir"), propPath); 097 if (propInUserDir.isFile() && !loadedFiles.contains(propInUserDir)) { 098 loadProperties(propInUserDir.toURI().toURL(), props); 099 loadedFiles.add(propInUserDir); 100 } 101 } catch (Exception e) { 102 } 103 104 // 输出所有参数值 105 if(showProp){ 106 props.list(System.out); 107 } 108 return props; 109 } 110 111 /** 112 * 基于user.home,加载相对路径propPath指定的properties文件 113 * @param propPath 114 * @return 115 */ 116 public static Properties loadPropertiesInUserHome(String propPath){ 117 Properties props = new Properties(); 118 try { 119 // 在user.home路径下查找配置文件 120 File propInUserHome = new File(System.getProperty("user.home"), propPath); 121 if (propInUserHome.isFile() ) { 122 loadProperties(propInUserHome.toURI().toURL(), props); 123 } 124 } catch (Exception e) { 125 } 126 return props; 127 } 128 /** 129 * 基于user.home,保存指定的{@link Properties} 130 * @param properties 131 * @param propertiesFile properties文件名 132 * @throws IOException 133 * @see Properties#store(java.io.Writer, String) 134 * @see System#getProperties() 135 */ 136 public static void storePropertiesInUserHome(Properties properties,String propertiesFile) throws IOException{ 137 if(null==properties){ 138 throw new NullPointerException(); 139 } 140 if(null==propertiesFile||propertiesFile.isEmpty()){ 141 throw new IllegalArgumentException("propertiesFile must not be empty or null"); 142 } 143 File propInUserHome = new File(System.getProperty("user.home"), propertiesFile); 144 File parent=propInUserHome.getParentFile(); 145 if(!parent.exists()){ 146 parent.mkdirs(); 147 } 148 properties.store(new FileWriter(propInUserHome), null); 149 150 } 151 /** 152 * configure with the parameters given in the given url 153 * 154 * @param url 155 * the resource filename to be used 156 * @param props 157 * dest properties to add 158 * @throws IOException 159 */ 160 private static void loadProperties(URL url, Properties props) throws IOException { 161 if (null != url) { 162 InputStream is = null; 163 try { 164 props.load(new InputStreamReader(is = url.openStream(),"UTF-8")); 165 log("Load properties from %s", url.toString()); 166 } finally { 167 if (is != null){ 168 is.close(); 169 } 170 } 171 } 172 } 173}